Bardzo zbliżone przybliżone (ignorując wszelkie transakcje w locie) to:
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 zwróci dużo, dużo szybciej niż COUNT(*)
, a jeśli twoja tabela zmienia się wystarczająco szybko, to nie jest wcale mniej dokładna - jeśli twoja tabela zmieniła się między rozpoczęciem COUNT (i zostały podjęte blokady) a jej zwróceniem (kiedy blokady zostały zwolnione i wszystkie oczekujące transakcje zapisu pozwolono teraz pisać do stołu), czy jest to o wiele bardziej wartościowe? Nie sądzę.
Jeśli masz jakiś podzbiór tabeli, którą chcesz policzyć (powiedz, WHERE some_column IS NULL
), możesz utworzyć filtrowany indeks w tej kolumnie i ustrukturyzować klauzulę WHERE w taki czy inny sposób, w zależności od tego, czy był to wyjątek, czy reguła (a zatem utwórz filtrowany indeks w mniejszym zestawie). Więc jeden z tych dwóch indeksów:
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;
Następnie możesz uzyskać liczbę w podobny sposób, używając:
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 jeśli chcesz wiedzieć coś przeciwnego, po prostu odejmij od pierwszego zapytania powyżej.