Ich arbeite im SQL Server-Team und kann hoffentlich einige Punkte in diesem Thread klären (ich hatte ihn vorher nicht gesehen, daher tut es mir leid, dass das Ingenieurteam dies nicht schon früher getan hat).
Erstens gibt es keinen semantischen Unterschied zwischen select count(1) from table
vs. select count(*) from table
. Sie liefern in allen Fällen die gleichen Ergebnisse (und wenn nicht, handelt es sich um einen Fehler). Wie in den anderen Antworten erwähnt, select count(column) from table
ist semantisch anders und liefert nicht immer die gleichen Ergebnisse wie count(*)
.
Zweitens gibt es im Hinblick auf die Leistung zwei Aspekte, die bei SQL Server (und SQL Azure) von Bedeutung sind: Arbeit bei der Kompilierung und Arbeit bei der Ausführung. Der Aufwand für die Kompilierungszeit ist in der aktuellen Implementierung trivialerweise gering. In einigen Fällen kommt es zu einer Erweiterung der * auf alle Spalten, gefolgt von einer Reduzierung auf eine Spalte, die aufgrund der Art und Weise, wie einige der internen Operationen bei der Bindung und Optimierung funktionieren, ausgegeben wird. Ich bezweifle, dass sich dies in einem messbaren Test bemerkbar machen würde, und es würde wahrscheinlich im Rauschen all der anderen Dinge untergehen, die im Verborgenen passieren (wie z. B. Auto-Stats, Xevent-Sitzungen, Abfragespeicher-Overhead, Trigger usw.). Es sind vielleicht ein paar tausend zusätzliche CPU-Anweisungen. count(1) macht also ein winziges bisschen weniger Arbeit während der Kompilierung (die in der Regel einmal stattfindet und der Plan über mehrere nachfolgende Ausführungen hinweg zwischengespeichert wird). Was die Ausführungszeit angeht, sollte es keinen messbaren Unterschied geben, vorausgesetzt, die Pläne sind gleich. (Eines der früheren Beispiele zeigt einen Unterschied - dieser ist höchstwahrscheinlich auf andere Faktoren auf der Maschine zurückzuführen, wenn der Plan derselbe ist).
Wie kann der Plan möglicherweise anders aussehen? Es ist äußerst unwahrscheinlich, dass dies geschieht, aber bei der Architektur des aktuellen Optimierers ist es potenziell möglich. Der Optimierer von SQL Server funktioniert wie ein Suchprogramm (man denke an ein Schach spielendes Computerprogramm, das verschiedene Alternativen für verschiedene Teile der Abfrage durchsucht und die Alternativen durchrechnet, um den günstigsten Plan in angemessener Zeit zu finden). Diese Suche unterliegt einigen Einschränkungen, damit die Abfragekompilierung in angemessener Zeit abgeschlossen werden kann. Für Abfragen, die über die trivialsten hinausgehen, gibt es Suchphasen, die sich mit Tranchen von Abfragen befassen, je nachdem, wie kostspielig der Optimierer die potenzielle Ausführung der Abfrage einschätzt. Es gibt drei Hauptsuchphasen, und in jeder Phase können aggressivere (teure) Heuristiken ausgeführt werden, um einen Plan zu finden, der billiger ist als jede vorherige Lösung. Am Ende jeder Phase gibt es einen Entscheidungsprozess, der versucht zu bestimmen, ob der bisher gefundene Plan zurückgegeben oder die Suche fortgesetzt werden soll. Bei diesem Prozess wird die bisher benötigte Gesamtzeit gegen die geschätzten Kosten des besten bisher gefundenen Plans abgewogen. Auf verschiedenen Rechnern mit unterschiedlich schnellen CPUs ist es also möglich (wenn auch selten), unterschiedliche Pläne zu erhalten, weil man in einer früheren Phase mit einem Plan aufhört und in der nächsten Suchphase weitersucht. Es gibt auch einige ähnliche Szenarien im Zusammenhang mit der Zeitüberschreitung in der letzten Phase und dem potenziellen Auslaufen des Speichers bei sehr, sehr teuren Abfragen, die den gesamten Speicher des Rechners verbrauchen (normalerweise kein Problem auf 64-Bit-Servern, aber auf 32-Bit-Servern war dies ein größeres Problem). Letztendlich würde sich die Leistung zur Laufzeit unterscheiden, wenn Sie einen anderen Plan erhalten. Ich halte es für unwahrscheinlich, dass der Unterschied in der Kompilierungszeit JEMALS zu einer dieser Bedingungen führen würde.
Netz-Netz: Bitte verwenden Sie, was auch immer Sie wollen, da nichts davon in irgendeiner praktischen Form von Bedeutung ist. (Ehrlich gesagt gibt es weitaus größere Faktoren, die sich auf die Leistung von SQL auswirken als dieses Thema).
Ich hoffe, das hilft. Ich habe ein Buchkapitel darüber geschrieben, wie der Optimierer funktioniert, aber ich weiß nicht, ob es angemessen ist, es hier zu veröffentlichen (da ich, glaube ich, immer noch kleine Tantiemen dafür bekomme). Anstatt das zu posten, werde ich einen Link zu einem Vortrag posten, den ich auf der SQLBits in Großbritannien über die Funktionsweise des Optimierers auf hohem Niveau gehalten habe, damit Sie die verschiedenen Hauptphasen der Suche etwas detaillierter sehen können, wenn Sie mehr darüber erfahren möchten. Hier ist der Video-Link: https://sqlbits.com/Sessions/Event6/inside_the_sql_server_query_optimizer