Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Count(*) vs. Count(Id) in SQL Server 2005

Thilo hat den Unterschied genau getroffen ... COUNT( column_name ) kann eine niedrigere Zahl als COUNT( * ) zurückgeben wenn column_name kann NULL sein .

Wenn ich Ihre Frage jedoch aus einem etwas anderen Blickwinkel beantworten darf, da Sie sich anscheinend auf die Leistung konzentrieren.

Beachten Sie zunächst, dass die Ausgabe von SELECT COUNT(*) FROM table; blockiert möglicherweise Schreiber und wird auch von anderen Lesern/Schreibern blockiert, es sei denn, Sie haben die Isolationsstufe geändert (kneejerk tendiert dazu, WITH (NOLOCK) zu sein aber ich sehe eine vielversprechende Anzahl von Leuten, die endlich anfangen, an RCSI zu glauben). Das bedeutet, dass sich all diese DML-Anforderungen häufen, während Sie die Daten lesen, um Ihre "genaue" Zählung zu erhalten, und wenn Sie schließlich alle Ihre Sperren freigegeben haben, öffnen sich die Schleusentore, ein Haufen Einfügen/Aktualisieren/Löschen Aktivität passiert, und da geht Ihre "genaue" Zählung.

Wenn Sie eine absolut transaktionskonsistente und genaue Zeilenanzahl benötigen (selbst wenn sie nur für die Anzahl der Millisekunden gültig ist, die benötigt wird, um die Zahl an Sie zurückzugeben), dann SELECT COUNT( * ) ist Ihre einzige Wahl.

Wenn Sie andererseits versuchen, eine zu 99,9 % genaue Schätzung zu erhalten, sind Sie mit einer Abfrage wie dieser viel besser dran:

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

(Die SUM ist da, um partitionierte Tabellen zu berücksichtigen - wenn Sie keine Tabellenpartitionierung verwenden, können Sie sie weglassen.)

Diese DMV verwaltet genaue Zeilenzahlen für Tabellen mit Ausnahme von Zeilen, die derzeit an Transaktionen teilnehmen - und genau diese Transaktionen sind diejenigen, die Ihre SELECT COUNT ergeben Abfrage warten (und sie letztendlich ungenau machen, bevor Sie Zeit haben, sie zu lesen). Aber ansonsten führt dies zu einer viel schnelleren Antwort als die von Ihnen vorgeschlagene Abfrage und nicht weniger genau als die Verwendung von WITH (NOLOCK) .