Aproximado muito próximo (ignorando quaisquer transações em voo) seria:
SELECT SUM(p.rows) FROM sys.partitions AS p
INNER JOIN sys.tables AS t
ON p.[object_id] = t.[object_id]
INNER JOIN sys.schemas AS s
ON s.[schema_id] = t.[schema_id]
WHERE t.name = N'myTable'
AND s.name = N'dbo'
AND p.index_id IN (0,1);
Isso retornará muito, muito mais rápido que
COUNT(*)
, e se sua tabela está mudando rápido o suficiente, não é realmente menos precisa - se sua tabela mudou entre quando você iniciou sua COUNT (e bloqueios foram obtidos) e quando ela foi retornada (quando os bloqueios foram liberados e todas as transações de gravação em espera agora foram autorizados a escrever na mesa), é muito mais valioso? Eu não acho. Se você tiver algum subconjunto da tabela que deseja contar (digamos,
WHERE some_column IS NULL
), você pode criar um índice filtrado nessa coluna e estruturar a cláusula where de uma forma ou de outra, dependendo se foi a exceção ou a regra (portanto, crie o índice filtrado no conjunto menor). Então, um desses dois índices:CREATE INDEX IAmTheException ON dbo.table(some_column)
WHERE some_column IS NULL;
CREATE INDEX IAmTheRule ON dbo.table(some_column)
WHERE some_column IS NOT NULL;
Então você pode obter a contagem de maneira semelhante usando:
SELECT SUM(p.rows) FROM sys.partitions AS p
INNER JOIN sys.tables AS t
ON p.[object_id] = t.[object_id]
INNER JOIN sys.schemas AS s
ON s.[schema_id] = t.[schema_id]
INNER JOIN sys.indexes AS i
ON p.index_id = i.index_id
WHERE t.name = N'myTable'
AND s.name = N'dbo'
AND i.name = N'IAmTheException' -- or N'IAmTheRule'
AND p.index_id IN (0,1);
E se você quiser saber o contrário, basta subtrair da primeira consulta acima.