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)
.