209 Stimmen

Was ist schneller/bester? SELECT * oder SELECT Spalte1, Spalte2, Spalte3, usw.

Ich habe gehört, dass SELECT * beim Schreiben von SQL-Befehlen zu verwenden, da es effizienter ist, die SELECT Spalten, die Sie speziell benötigen.

Wenn ich es brauche SELECT jede Spalte in einer Tabelle, sollte ich

SELECT * FROM TABLE

o

SELECT column1, colum2, column3, etc. FROM TABLE

Spielt die Effizienz in diesem Fall wirklich eine Rolle? Ich würde denken SELECT * wäre intern optimaler, wenn Sie wirklich alle Daten benötigen, aber ich sage das, ohne wirklich etwas von Datenbanken zu verstehen.

Ich bin neugierig, was in diesem Fall die beste Praxis ist.

UPDATE: Ich sollte vielleicht präzisieren, dass die einzige Situation, in der ich wirklich wollen um eine SELECT * ist, wenn ich Daten aus einer Tabelle auswähle, von der ich weiß, dass immer alle Spalten abgerufen werden müssen, auch wenn neue Spalten hinzugefügt werden.

In Anbetracht der Reaktionen, die ich gesehen habe, scheint dies jedoch immer noch eine schlechte Idee zu sein und SELECT * sollte aus viel mehr technischen Gründen, als ich je bedacht habe, niemals verwendet werden.

196voto

Jon Galloway Punkte 51200

Ein Grund dafür, dass die Auswahl bestimmter Spalten besser ist, besteht darin, dass dadurch die Wahrscheinlichkeit erhöht wird, dass SQL Server auf die Daten über Indizes zugreifen kann, anstatt die Tabellendaten abzufragen.

Hier ist ein Beitrag, den ich darüber geschrieben habe: Der wahre Grund für die schlechte Indexabdeckung von Select-Abfragen

Es ist auch weniger anfällig für Änderungen, da jeder Code, der die Daten abruft, dieselbe Datenstruktur erhält, unabhängig davon, ob Sie das Tabellenschema in Zukunft ändern.

67voto

IDisposable Punkte 1827

Gegeben Ihr Spezifikation, die Sie sind alle Spalten auswählen, gibt es kaum einen Unterschied zum jetzigen Zeitpunkt . Beachten Sie jedoch, dass sich Datenbankschemata ändern können. Wenn Sie *`SELECT `** erhalten Sie alle neuen Spalten, die der Tabelle hinzugefügt werden, auch wenn Ihr Code höchstwahrscheinlich nicht darauf vorbereitet ist, diese neuen Daten zu verwenden oder darzustellen. Dies bedeutet, dass Sie Ihr System unerwarteten Leistungs- und Funktionsänderungen aussetzen.

Sie sind vielleicht bereit, dies als geringfügige Kosten abzutun, aber Sie sollten sich darüber im Klaren sein, dass Säulen, die Sie nicht brauchen, trotzdem vorhanden sein müssen:

  1. Lesen aus der Datenbank
  2. Über das Netzwerk gesendet
  3. Eingebunden in Ihren Prozess
  4. (für ADO-artige Technologien) Gespeichert in einer Daten-Tabelle im Speicher
  5. Ignoriert und weggeworfen / im Müll gesammelt

Punkt 1 hat viele versteckte Kosten, einschließlich der Beseitigung einiger potenzieller abdeckender Indizes, der Belastung von Datenseiten (und des Cache des Servers) und der Verursachung von Zeilen-/Seiten-/Tabellensperren, die ansonsten vermieden werden könnten.

Wägen Sie dies gegen die potenziellen Einsparungen ab, die durch die Angabe der Säulen im Vergleich zu einer *``** und die einzigen möglichen Einsparungen sind:

  1. Der Programmierer muss die SQL nicht erneut aufrufen, um Spalten hinzuzufügen.
  2. Der Netzwerk-Transport des SQL ist kleiner / schneller
  3. SQL Server Abfrage Parse-/Validierungszeit
  4. SQL Server Abfrageplan-Cache

Für Punkt 1, die Realität ist, dass Sie gehen, um hinzuzufügen / ändern Sie den Code, um jede neue Spalte, die Sie sowieso hinzufügen könnte, so ist es eine Wäsche.

Bei Punkt 2 ist der Unterschied selten groß genug, um eine andere Paketgröße oder Anzahl von Netzwerkpaketen zu erreichen. Wenn Sie an einen Punkt gelangen, an dem die Zeit für die Übertragung von SQL-Anweisungen das Hauptproblem darstellt, müssen Sie wahrscheinlich zuerst die Anzahl der Anweisungen reduzieren.

Bei Punkt 3 gibt es KEINE Einsparungen, da die Erweiterung des *``** ohnehin geschehen muss, was bedeutet, dass das Tabellenschema ohnehin konsultiert werden muss. Realistischerweise verursacht die Auflistung der Spalten die gleichen Kosten, da sie anhand des Schemas validiert werden müssen. Mit anderen Worten: Es ist ein kompletter Reinfall.

Für Punkt 4, wenn Sie bestimmte Spalten angeben, könnte Ihr Abfrageplan-Cache größer werden, aber nur wenn es sich um verschiedene Spaltengruppen handelt (was Sie nicht angegeben haben). In diesem Fall müssen Sie wollen verschiedene Cache-Einträge, da Sie je nach Bedarf verschiedene Pläne wünschen.

Aufgrund der Art und Weise, wie Sie die Frage formuliert haben, läuft alles auf das Problem der Widerstandsfähigkeit angesichts eventueller Schemaänderungen hinaus. Wenn Sie dieses Schema in ROM brennen (was vorkommt), dann wird ein *``** ist vollkommen akzeptabel.

Meine allgemeine Richtlinie lautet jedoch, dass Sie nur die Spalten auswählen sollten, die Sie benötigen, d. h. manchmal Es sieht so aus, als würden Sie nach allen Spalten fragen, aber DBAs und Schemaentwicklungen bedeuten, dass einige neue Spalten auftauchen können, die die Abfrage stark beeinflussen können.

Mein Rat ist, dass Sie ALWAYS SELECT bestimmte Spalten . Denken Sie daran, dass man gut wird in dem, was man immer wieder tut, also gewöhnen Sie sich an, es richtig zu machen.

Wenn Sie sich fragen, warum sich ein Schema ändern kann, ohne dass sich der Code ändert, denken Sie an die Audit-Protokollierung, das Gültigkeits-/Ablaufdatum und ähnliche Dinge, die von DBAs aus Gründen der Systemkonformität hinzugefügt werden. Eine weitere Quelle für unbemerkte Änderungen sind Denormalisierungen zur Leistungssteigerung an anderer Stelle im System oder benutzerdefinierte Felder.

43voto

Giorgi Punkte 29625

Sie sollten nur die Spalten auswählen, die Sie benötigen. Auch wenn Sie alle Spalten benötigen, ist es besser, die Spaltennamen aufzulisten, damit der Sql-Server nicht die Systemtabelle nach Spalten abfragen muss.

Außerdem könnte Ihre Anwendung abbrechen, wenn jemand der Tabelle Spalten hinzufügt. Ihr Programm erhält dann Spalten, die es nicht erwartet hat, und weiß möglicherweise nicht, wie es sie verarbeiten soll.

Abgesehen davon, wenn die Tabelle eine binäre Spalte hat, wird die Abfrage viel langsamer sein und mehr Netzwerkressourcen verbrauchen.

38voto

pkh Punkte 3319

Es gibt vier wichtige Gründe, die select * ist eine schlechte Sache:

  1. Der wichtigste praktische Grund ist, dass der Benutzer auf magische Weise weiß, in welcher Reihenfolge die Spalten zurückgegeben werden. Es ist besser, explizit zu sein, was Sie auch davor schützt, dass sich die Tabelle ändert, was eine gute Überleitung zu...

  2. Wenn sich der Name einer Spalte, die Sie verwenden, ändert, ist es besser, dies frühzeitig zu erkennen (zum Zeitpunkt des SQL-Aufrufs), als wenn Sie versuchen, die Spalte zu verwenden, die nicht mehr existiert (oder deren Name geändert wurde usw.).

  3. Durch die Auflistung der Spaltennamen wird Ihr Code viel selbstdokumentierter und damit wahrscheinlich auch lesbarer.

  4. Wenn Sie über ein Netzwerk übertragen (oder auch nicht), sind Spalten, die Sie nicht benötigen, reine Verschwendung.

10voto

Herb Caudill Punkte 49603

Die Angabe von Spaltennamen ist definitiv schneller - für den Server. Aber wenn

  1. Leistung ist kein großes Thema (z. B. handelt es sich um eine Website-Inhaltsdatenbank mit Hunderten, vielleicht Tausenden - aber nicht Millionen - von Zeilen in jeder Tabelle); UND
  2. Ihre Aufgabe ist es, die viele kleine, ähnliche Anwendungen (z. B. öffentlich zugängliche, inhaltsverwaltete Websites) unter Verwendung eines gemeinsamen Rahmens, anstatt eine komplexe Einzelanwendung zu erstellen; UND
  3. Flexibilität ist wichtig (zahlreiche Anpassungen des Datenbankschemas für jede Website);

dann ist es besser, bei SELECT * zu bleiben. In unserem Framework können wir mit SELECT * ein neues, von der Website verwaltetes Inhaltsfeld in eine Tabelle einfügen und so alle Vorteile des CMS (Versionierung, Workflow/Genehmigungen usw.) nutzen, während wir den Code nur an einigen wenigen Stellen anfassen, anstatt an mehreren Dutzend Stellen.

Ich weiß, dass die DB-Gurus mich dafür hassen werden - nur zu, wählen Sie mich ab - aber in meiner Welt ist Entwicklerzeit knapp und CPU-Zyklen sind im Überfluss vorhanden, also passe ich entsprechend an, was ich einspare und was ich verschwende.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X