Velmi blízká přibližná hodnota (ignorování všech transakcí během letu) by byla:
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);
To se vrátí mnohem, mnohem rychleji než COUNT(*)
a pokud se vaše tabulka mění dostatečně rychle, není to ve skutečnosti o nic méně přesné – pokud se vaše tabulka změnila mezi okamžikem, kdy jste spustili COUNT (a byly uzamčeny), a okamžikem, kdy byl vrácen (když byly zámky uvolněny a všechny čekající transakce zápisu nyní bylo dovoleno psát na stůl), je to o to cennější? Myslím, že ne.
Pokud máte nějakou podmnožinu tabulky, kterou chcete spočítat (řekněme WHERE some_column IS NULL
), můžete v tomto sloupci vytvořit filtrovaný index a strukturovat klauzuli where tak či onak, v závislosti na tom, zda se jednalo o výjimku nebo pravidlo (takže vytvořte filtrovaný index na menší sadě). Takže jeden z těchto dvou indexů:
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;
Potom byste mohli získat počet podobným způsobem pomocí:
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);
A pokud chcete vědět opak, stačí odečíst od prvního dotazu výše.