Thilo slog fast skillnaden exakt... COUNT( column_name )
kan returnera ett lägre tal än COUNT( * )
om column_name
kan vara NULL
.
Men om jag kan ta en lite annan vinkel på att svara på din fråga, eftersom du verkar fokusera på prestanda.
Observera först att du utfärdar SELECT COUNT(*) FROM table;
kommer potentiellt att blockera skribenter, och det kommer också att blockeras av andra läsare/skribenter såvida du inte har ändrat isoleringsnivån (knee-ryck tenderar att vara WITH (NOLOCK)
men jag ser att ett lovande antal människor äntligen börjar tro på RCSI). Vilket betyder att medan du läser informationen för att få din "korrekta" räkning, hopar sig alla dessa DML-förfrågningar, och när du äntligen har släppt alla dina lås öppnas slussarna, ett gäng infoga/uppdatera/ta bort aktivitet händer, och där går din "exakta" räkning.
Om du behöver ett absolut transaktionellt konsekvent och korrekt radantal (även om det bara är giltigt för det antal millisekunder som det tar att returnera numret till dig), så SELECT COUNT( * )
är ditt enda val.
Å andra sidan, om du försöker få en 99,9 % korrekt bollplank är du mycket bättre med en fråga som denna:
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
finns det för att ta hänsyn till partitionerade tabeller - om du inte använder tabellpartitionering kan du utelämna det.)
Denna DMV upprätthåller korrekt radantal för tabeller med undantag för rader som för närvarande deltar i transaktioner - och just dessa transaktioner är de som kommer att göra ditt SELECT COUNT
fråga vänta (och slutligen göra den felaktig innan du hinner läsa den). Men annars kommer detta att leda till ett mycket snabbare svar än frågan du föreslår, och inte mindre exakt än att använda WITH (NOLOCK)
.