Thilo dokładnie określił różnicę... COUNT( column_name ) może zwrócić mniejszą liczbę niż COUNT( * ) jeśli column_name może być NULL .
Jeśli jednak mogę odpowiedzieć na twoje pytanie z nieco innego punktu widzenia, ponieważ wydajesz się skupiać na wydajności.
Po pierwsze, zwróć uwagę, że wywoływanie tabeli SELECT COUNT(*) FROM table; potencjalnie zablokuje pisarzy, a także zostanie zablokowany przez innych czytelników/piszących, chyba że zmieniłeś poziom izolacji (odruch kolanowy ma tendencję do WITH (NOLOCK) ale widzę obiecującą liczbę ludzi, którzy w końcu zaczynają wierzyć w RCSI). Oznacza to, że kiedy czytasz dane, aby uzyskać „dokładną” liczbę, wszystkie te żądania DML narastają, a kiedy w końcu zwolnisz wszystkie swoje blokady, śluzy otwierają się, kilka operacji wstawiania/aktualizowania/usuwania dzieje się aktywność, a także twoja „dokładna” liczba.
Jeśli potrzebujesz absolutnie spójnej transakcyjnie i dokładnej liczby wierszy (nawet jeśli jest ona ważna tylko przez liczbę milisekund potrzebną do zwrócenia ci liczby), wtedy SELECT COUNT( * ) to jedyny wybór.
Z drugiej strony, jeśli próbujesz uzyskać 99,9% dokładności, znacznie lepiej jest z zapytaniem takim jak to:
SELECT row_count = SUM(row_count)
FROM sys.dm_db_partition_stats
WHERE [object_id] = OBJECT_ID('dbo.Table')
AND index_id IN (0,1);
(SUM ma uwzględniać partycjonowane tabele - jeśli nie używasz partycjonowania tabel, możesz to pominąć.)
Ten DMV utrzymuje dokładną liczbę wierszy dla tabel z wyjątkiem wierszy, które obecnie uczestniczą w transakcjach - i te właśnie transakcje sprawią, że SELECT COUNT zapytanie czekać (i ostatecznie sprawić, że będzie niedokładne, zanim zdążysz je przeczytać). Ale w przeciwnym razie doprowadzi to do znacznie szybszej odpowiedzi niż zapytanie, które proponujesz, i nie mniej dokładnej niż użycie WITH (NOLOCK) .