Welches ist schneller / am besten? SELECT * oder SELECT Spalte1, Spalte2, Spalte3 usw.


166

Ich habe gehört, dass dies SELECT *beim Schreiben von SQL-Befehlen im Allgemeinen eine schlechte Praxis ist, da es für SELECTSpalten, die Sie speziell benötigen, effizienter ist .

Wenn ich zu SELECTjeder Spalte in einer Tabelle muss, sollte ich verwenden

SELECT * FROM TABLE

oder

SELECT column1, colum2, column3, etc. FROM TABLE

Ist die Effizienz in diesem Fall wirklich wichtig? Ich würde denken SELECT *, dass es intern optimaler wäre, wenn Sie wirklich alle Daten benötigen, aber ich sage dies ohne wirkliches Verständnis der Datenbank.

Ich bin gespannt, was in diesem Fall die beste Vorgehensweise ist.

UPDATE: Ich sollte wahrscheinlich angeben, dass die einzige Situation, in der ich wirklich etwas tun möchte , darin SELECT *besteht, Daten aus einer Tabelle auszuwählen, in der ich weiß, dass alle Spalten immer abgerufen werden müssen, auch wenn neue Spalten hinzugefügt werden.

Angesichts der Antworten, die ich gesehen habe, scheint dies jedoch immer noch eine schlechte Idee zu sein und SELECT *sollte niemals aus viel mehr technischen Gründen verwendet werden, über die ich jemals nachgedacht habe.




1
Ja, es ist ein Duplikat der meisten davon.
George Stocker

Antworten:


168

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

Hier ist ein Beitrag, den ich darüber geschrieben habe: Der wahre Grund für ausgewählte Abfragen ist eine schlechte Indexabdeckung

Änderungen sind auch weniger fragil, da jeder Code, der die Daten verbraucht, unabhängig von Änderungen, die Sie in Zukunft am Tabellenschema vornehmen, dieselbe Datenstruktur erhält.


3
+1 dafür. Wenn alle Spalten, auf die verwiesen wird, in einem einzigen Index (einem "Deckungsindex") vorhanden sind, haben Sie Gold geschlagen.
Ian Nelson

22
Das ist nicht die Antwort auf seine Frage - "Wenn ich jede Spalte in einer Tabelle auswählen muss, ..." - in diesem Fall spielt * vs col1, .., coln keine Rolle (aber es tut für die Programmiererzeit, da * kürzer ist!).
Matt Rogish

3
Dies ist weiterhin wichtig, da es sich bei der Auswahlliste um eine Vertragsform handelt, insbesondere wenn sich die SQL in einer gespeicherten Prozedur befindet.
Eric Z Beard

4
Während das, was Jon sagt, völlig richtig und ein sehr gültiger Punkt ist, muss ich zustimmen, dass es bei der Frage AS ASKED darum geht, ob sie bereits nach allen Spalten fragen. Aufgrund dieses Teils der Frage besteht das eigentliche Problem in der Fragilität angesichts von Schemaänderungen.
IDisposable

1
@MattRogish Sir, Sie haben es richtig verstanden. Gibt es einen Leistungsunterschied zwischen diesen beiden Methoden (* vsall_column_names), während wir Tausende von Zeilen haben und SELECT mit Index ausführen (in der WHERE-Klausel)?
Santosh

59

In Anbetracht Ihrer Spezifikation , dass Sie werden alle Spalten der Auswahl gibt es kaum einen Unterschied zu diesem Zeitpunkt . Beachten Sie jedoch, dass sich Datenbankschemata ändern. Wenn Sie verwenden SELECT *, werden der Tabelle neue Spalten hinzugefügt, obwohl Ihr Code aller Wahrscheinlichkeit nach nicht bereit ist, diese neuen Daten zu verwenden oder zu präsentieren. Dies bedeutet, dass Sie Ihr System unerwarteten Leistungs- und Funktionsänderungen aussetzen.

Sie sind möglicherweise bereit, dies als geringfügige Kosten abzutun, stellen jedoch fest, dass Spalten, die Sie noch nicht benötigen, Folgendes sein müssen:

  1. Aus Datenbank lesen
  2. Über das Netzwerk gesendet
  3. Marshalled in Ihren Prozess
  4. (für ADO-Technologien) In einer Datentabelle im Speicher gespeichert
  5. Ignoriert und weggeworfen / Müll gesammelt

Artikel 1 hat viele versteckte Kosten, einschließlich der Eliminierung eines potenziellen Deckungsindex, der das Laden von Datenseiten (und das Thrashing des Server-Cache) und das Sperren von Zeilen / Seiten / Tabellen verursacht, die andernfalls vermieden werden könnten.

Vergleichen Sie dies mit den potenziellen Einsparungen bei der Angabe der Spalten im Vergleich zu an. *Die einzigen potenziellen Einsparungen sind:

  1. Der Programmierer muss SQL nicht erneut aufrufen, um Spalten hinzuzufügen
  2. Der Netzwerktransport des SQL ist kleiner / schneller
  3. Analyse- / Validierungszeit für SQL Server-Abfragen
  4. SQL Server-Abfrageplan-Cache

Für Punkt 1 ist die Realität, dass Sie Code hinzufügen / ändern, um jede neue Spalte zu verwenden, die Sie ohnehin hinzufügen könnten. Es handelt sich also um eine Wäsche.

Bei Punkt 2 reicht der Unterschied selten aus, um Sie in eine andere Paketgröße oder Anzahl von Netzwerkpaketen zu verschieben. Wenn Sie an einem Punkt angelangt sind, an dem die Übertragungszeit von SQL-Anweisungen das vorherrschende Problem ist, müssen Sie wahrscheinlich zuerst die Rate der Anweisungen reduzieren.

Für Punkt 3 gibt es KEINE Einsparungen, da die Erweiterung *ohnehin erfolgen muss, was bedeutet, dass das Schema der Tabelle (n) trotzdem konsultiert wird. Realistisch gesehen verursacht das Auflisten der Spalten die gleichen Kosten, da sie anhand des Schemas validiert werden müssen. Mit anderen Worten, dies ist eine vollständige Wäsche.

Wenn Sie für Punkt 4 bestimmte Spalten angeben, wird der Abfrageplan-Cache möglicherweise größer, jedoch nur, wenn Sie mit verschiedenen Spaltengruppen arbeiten (was nicht von Ihnen angegeben wurde). In diesem Fall möchten Sie unterschiedliche Cache-Einträge, da Sie nach Bedarf unterschiedliche Pläne wünschen.

Dies alles hängt aufgrund der Art und Weise, wie Sie die Frage angegeben haben, von der Ausfallsicherheit des Problems angesichts eventueller Schemaänderungen ab. Wenn Sie dieses Schema in ein ROM brennen (es passiert), ist ein *durchaus akzeptabel.

Meine allgemeine Richtlinie lautet jedoch, dass Sie nur die Spalten auswählen sollten, die Sie benötigen. Dies bedeutet, dass es manchmal so aussieht, als würden Sie nach allen fragen. DBAs und die Schemaentwicklung bedeuten jedoch, dass möglicherweise einige neue Spalten angezeigt werden, die die Abfrage stark beeinflussen können .

Mein Rat ist, dass Sie IMMER bestimmte Spalten AUSWÄHLEN sollten . Denken Sie daran, dass Sie immer wieder gut darin sind, was Sie tun. Gewöhnen Sie sich also einfach an, es richtig zu machen.

Wenn Sie sich fragen, warum sich ein Schema möglicherweise ändert, ohne dass sich der Code ändert, denken Sie an die Überwachungsprotokollierung, die Gültigkeits- / Ablaufdaten und andere ähnliche Dinge, die von DBAs systematisch für Compliance-Probleme hinzugefügt werden. Eine weitere Ursache für hinterhältige Änderungen sind Denormalisierungen für die Leistung an anderer Stelle im System oder in benutzerdefinierten Feldern.


3
"Die Realität ist, dass Sie Code hinzufügen / ändern werden, um jede neue Spalte zu verwenden, die Sie ohnehin hinzufügen könnten. Es ist also eine Wäsche." -Nur wenn Sie jede Spalte manuell nach Namen in Ihrem Code lesen. Wenn Sie die automatische Zuordnung verwenden, ist dies nicht der Fall, und dieses Problem wird erheblich.
Josh Noe

36

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

Außerdem kann Ihre Anwendung unterbrochen werden, wenn jemand der Tabelle Spalten hinzufügt. Ihr Programm erhält Spalten, die es nicht erwartet hat, und es weiß möglicherweise nicht, wie es verarbeitet werden soll.

Abgesehen davon, wenn die Tabelle eine Binärspalte enthält, ist die Abfrage viel langsamer und verwendet mehr Netzwerkressourcen.


6
Aha, mit * fügen Sie zusätzliche Arbeit für die Datenbank hinzu. Ok, das ist ein Grund, an den ich nicht gedacht hatte.
Ankur

1
+1 für das Risiko, Fehler frühzeitig zu brechen oder zu erkennen. Ich denke, die Diskussion über Effizienz ist gültig, aber YAGNI.
Nailitdown

6
Müsste der SQL Server nicht überprüfen oder prüfen, ob "col1" in der angegebenen Tabelle enthalten ist, dh die Abfragesystemtabelle?
Patrick

3
Der größte Leistungseinbruch hängt wahrscheinlich mit der Indizierung zusammen. Wenn die gesuchte Spalte Teil des Index ist, der zum Auffinden der Daten verwendet wird, ruft der Server die Daten genau dort ab. Wenn Sie eine Auswahl * treffen, muss er höchstwahrscheinlich eine sogenannte Lesezeichensuche durchführen, für die eine zusätzliche Suche erforderlich ist Scannen Sie, um den Rest der zugrunde liegenden Daten zu finden, die Sie möglicherweise nicht einmal benötigen.
Cobusve

3
@Patrick - genau richtig. Viele gute Gründe, dies zu vermeiden *, aber das ist keiner von ihnen.
Martin Smith

31

Es gibt vier große Gründe, die select *schlecht sind:

  1. Der wichtigste praktische Grund ist, dass der Benutzer gezwungen ist, die Reihenfolge, in der die Spalten zurückgegeben werden, auf magische Weise zu kennen. Es ist besser, explizit zu sein, was Sie auch vor dem Tischwechsel schützt, der sich gut in ...

  2. Wenn sich ein Spaltenname, den Sie verwenden, ändert, ist es besser, ihn frühzeitig (zum Zeitpunkt des SQL-Aufrufs) abzufangen, als wenn Sie versuchen, die Spalte zu verwenden, die nicht mehr vorhanden ist (oder deren Name geändert wurde usw.). )

  3. Durch das Auflisten der Spaltennamen wird Ihr Code weitaus selbstdokumentierter und daher wahrscheinlich besser lesbar.

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


7
"Der wichtigste praktische Grund ist, dass der Benutzer gezwungen ist, die Reihenfolge, in der die Spalten zurückgegeben werden, auf magische Weise zu kennen." Ich sehe nicht, wie das ein Problem ist. In jedem modernen DB-Client lesen Sie Spalten nach Namen und nicht nach Reihenfolge.
Josh Noe

Ich neige dazu, mein SQL über eine C-Schnittstelle auszuführen, daher würde ich nicht wirklich wissen, wie der Stand der Technik in "DB-Clients" ist. Aber ich denke, wahrscheinlich ist die Art von Client, über die Sie sprechen, eine nicht standardmäßige Nicht-SQL-Magie. (z. B. in SQLite, wenn Sie sqlite3_master abfragen, um herauszufinden, wie Sie Ihre Namen *in eine Reihe von Namen ändern können .)
pkh

Und weiter davon, wie viele Leute schreiben Code in modernen Anwendungen, die entweder den Index der Spaltennamen verwenden? Die meisten Leute verwenden sicherlich eine Art Mapper und einen ganzen Haufen Caching für Daten, die veraltet sein dürfen. Schreiben Sie persönlich zuerst den Code und machen Sie sich dann Sorgen, wenn Sie später Leistungsprobleme haben.
Colin Wiseman

10

Das Angeben der Spaltenliste ist normalerweise die beste Option, da Ihre Anwendung nicht betroffen ist, wenn jemand eine Spalte zur Tabelle hinzufügt / einfügt.


7

Das Angeben von Spaltennamen ist definitiv schneller - für den Server. Aber falls

  1. Leistung ist kein großes Problem (zum Beispiel ist dies eine Website-Inhaltsdatenbank mit Hunderten, vielleicht Tausenden - aber nicht Millionen - Zeilen in jeder Tabelle); UND
  2. Ihre Aufgabe ist es, viele kleine, ähnliche Anwendungen (z. B. öffentlich zugängliche, inhaltsverwaltete Websites) mithilfe eines gemeinsamen Frameworks zu erstellen, anstatt eine komplexe einmalige Anwendung zu erstellen. UND
  3. Flexibilität ist wichtig (viele Anpassungen des Datenbankschemas für jede Site);

Dann bleiben Sie besser bei SELECT *. In unserem Framework können wir durch die häufige Verwendung von SELECT * ein neues, von der Website verwaltetes Inhaltsfeld in eine Tabelle einfügen, das alle Vorteile des CMS (Versionierung, Workflow / Genehmigungen usw.) bietet, während wir nur den Code bei a berühren ein paar Punkte statt ein paar Dutzend Punkte.

Ich weiß, dass die DB-Gurus mich dafür hassen werden - machen Sie weiter, stimmen Sie mich ab -, aber in meiner Welt ist die Entwicklerzeit knapp und die CPU-Zyklen sind reichlich vorhanden. Deshalb passe ich entsprechend an, was ich konserviere und was ich verschwende.


1
Es macht auch die Verwendung von ORMs viel einfacher. Wenn Abfragen durch Weitergeben eines Abfrageerstellungsobjekts erstellt werden, ist nicht unbedingt bekannt, welche Spalten für welche anderen Codeteile erforderlich waren (Berechtigungsprüfungen, welche haben Sie). Um die Spalten einzuschränken, müsste jedes Mal untersucht werden, wenn eine Abfrage geschrieben werden muss. Das ist sinnlos, IMO. Wenn sich Abfragen als langsam herausstellen (Protokolle!), Kann man diese verbessern.
Bytepusher

6

SELECT * ist eine schlechte Praxis, auch wenn die Abfrage nicht über ein Netzwerk gesendet wird.

  1. Wenn Sie mehr Daten auswählen, als Sie benötigen, wird die Abfrage weniger effizient. Der Server muss zusätzliche Daten lesen und übertragen. Dies nimmt Zeit in Anspruch und belastet das System unnötig (nicht nur das Netzwerk, wie bereits erwähnt, sondern auch die Festplatte, die CPU usw.). ). Darüber hinaus kann der Server die Abfrage nicht so gut wie möglich optimieren (verwenden Sie beispielsweise den Deckungsindex für die Abfrage).
  2. Nach einiger Zeit kann sich Ihre Tabellenstruktur ändern, sodass SELECT * einen anderen Satz von Spalten zurückgibt. Daher erhält Ihre Anwendung möglicherweise einen Datensatz mit unerwarteter Struktur und bricht irgendwo stromabwärts ab. Die explizite Angabe der Spalten garantiert, dass Sie entweder einen Datensatz mit bekannter Struktur oder einen eindeutigen Fehler auf Datenbankebene erhalten (z. B. "Spalte nicht gefunden").

Natürlich ist das alles für ein kleines und einfaches System nicht wichtig.


4

In Bezug auf die Leistung kann SELECT mit bestimmten Spalten schneller sein (es müssen nicht alle Daten eingelesen werden). Wenn Ihre Abfrage wirklich ALLE Spalten verwendet, wird SELECT mit expliziten Parametern weiterhin bevorzugt. Jeder Geschwindigkeitsunterschied ist grundsätzlich unbemerkt und nahezu zeitkonstant. Eines Tages wird sich Ihr Schema ändern, und dies ist eine gute Versicherung, um Probleme aufgrund dieser zu vermeiden.


Sie irren sich über das Unmerkliche, da bei Überprüfungen, die ich mit mehreren DBs durchgeführt habe, klar war, dass die Auswahl jeder Spalte, auch wenn alle, viel schneller ist. In einigen Fällen war es dreimal schneller.
Shahar Eldad

4

Viele gute Gründe haben hier bisher geantwortet, hier ist ein weiterer, der nicht erwähnt wurde.

Die explizite Benennung der Spalten hilft Ihnen bei der späteren Wartung. Irgendwann werden Sie Änderungen vornehmen oder Fehler beheben und sich fragen: "Wo zum Teufel wird diese Spalte verwendet?".

Wenn Sie die Namen explizit aufgelistet haben, ist es einfach, jeden Verweis auf diese Spalte - über alle Ihre gespeicherten Prozeduren, Ansichten usw. - zu finden. Speichern Sie einfach ein CREATE-Skript für Ihr DB-Schema und durchsuchen Sie es mit Text.


3

Definieren Sie die Spalten definitiv, da SQL Server die Spalten nicht nachschlagen muss, um sie abzurufen. Wenn Sie die Spalten definieren, kann SQL diesen Schritt überspringen.


Dies ist: 1) irrelevant, da SQL Server auf das Tabellenschema in beide Richtungen verweisen muss (um die Spaltennamen zu überprüfen oder die bekanntermaßen gültigen Spaltennamen nachzuschlagen). 2) Nicht relevant für die gestellte Frage, auf die alle Spalten verwiesen werden. Das einzige Problem, das gefragt wird, ist die Fragilität mit Schemaänderungen.
IDisposable

Downvoted, weil es die Spalten unabhängig validieren muss.
John Gibb

3

Es ist immer besser, die Spalten anzugeben, die Sie benötigen. Wenn Sie einmal darüber nachdenken, muss SQL nicht bei jeder Abfrage an "wtf is *" denken. Darüber hinaus kann später jemand der Tabelle Spalten hinzufügen, die Sie in Ihrer Abfrage tatsächlich nicht benötigen. In diesem Fall sind Sie besser dran, wenn Sie alle Ihre Spalten angeben.


1
Dies ist nicht wahr: SQL Server muss weiterhin jede Spalte analysieren und prüfen, ob sie in den Katalogen vorhanden ist, während er weiß, dass "*" dies tut (und ja, * wird auf alle Spalten erweitert). In beiden
Fällen

Ich denke, der bessere Punkt, dass viele fehlen und diese Antwort leider nur sekundär behandelt wird, ist, dass wenn Schema- / Tabellenänderungen auftreten (dh neue Spalten hinzugefügt werden), die Dinge nicht kaputt gehen.
Sean Hanley

1
Es ist eine vollständige Wäsche, da das Nachschlagen der Spalten für die * -Erweiterung mit dem Überprüfen der angegebenen Spaltennamen identisch ist.
IDisposable

3

Das Problem mit "select *" ist die Möglichkeit, Daten zu bringen, die Sie nicht wirklich benötigen. Während der eigentlichen Datenbankabfrage tragen die ausgewählten Spalten nicht wirklich zur Berechnung bei. Was wirklich "schwer" ist, ist der Datentransport zurück zu Ihrem Client. Jede Spalte, die Sie nicht wirklich benötigen, verschwendet nur die Netzwerkbandbreite und verlängert die Zeit, die Sie auf die Rückgabe Ihrer Abfrage warten.

Selbst wenn Sie alle Spalten verwenden, die aus einem "select * ..." stammen, ist dies nur für den Moment. Wenn Sie in Zukunft das Tabellen- / Ansichtslayout ändern und weitere Spalten hinzufügen, werden diese in Ihre Auswahl aufgenommen, auch wenn Sie sie nicht benötigen.

Ein weiterer Punkt, an dem eine "select *" - Anweisung schlecht ist, ist die Erstellung von Ansichten. Wenn Sie eine Ansicht mit "select *" erstellen und später Spalten zu Ihrer Tabelle hinzufügen, stimmen die Ansichtsdefinition und die zurückgegebenen Daten nicht überein, und Sie müssen Ihre Ansichten neu kompilieren, damit sie wieder funktionieren.

Ich weiß, dass das Schreiben eines "select *" verlockend ist, weil ich wirklich nicht gerne alle Felder in meinen Abfragen manuell spezifiziere, aber wenn sich Ihr System weiterentwickelt, werden Sie feststellen, dass es sich lohnt, diese zusätzliche Zeit zu verbringen / Aufwand bei der Angabe der Felder, anstatt viel mehr Zeit und Mühe damit zu verbringen, Fehler in Ihren Ansichten zu beseitigen oder Ihre App zu optimieren.


Der Punkt auf VIEWs ist sehr wichtig. Sie erhalten nicht nur nicht alle Spalten, wenn Sie der Tabelle Spalten hinzufügen (ungeachtet dessen, was Sie mit dem * denken würden), sondern sie stimmen möglicherweise nicht einmal mit dem tatsächlichen Layout der Tabelle überein.
Euro Micelli

3

Während das explizite Auflisten von Spalten gut für die Leistung ist, sollten Sie nicht verrückt werden.

Wenn Sie also alle Daten verwenden, versuchen Sie es der Einfachheit halber mit SELECT * (stellen Sie sich vor, Sie haben viele Spalten und führen eine JOIN ... -Abfrage durch, die möglicherweise schrecklich wird). Dann - messen. Vergleichen Sie mit der Abfrage mit explizit aufgeführten Spaltennamen.

Spekulieren Sie nicht über Leistung, messen Sie sie!

Die explizite Auflistung ist am hilfreichsten, wenn Sie eine Spalte mit großen Datenmengen (z. B. Text eines Beitrags oder Artikels) haben und diese in einer bestimmten Abfrage nicht benötigen. Wenn Sie es dann nicht in Ihrer Antwort zurückgeben, kann der DB-Server Zeit, Bandbreite und Festplattendurchsatz sparen. Ihr Abfrageergebnis ist auch kleiner, was für jeden Abfragecache gut ist.


3

Sie sollten wirklich nur die Felder auswählen, die Sie benötigen, und nur die erforderliche Anzahl, dh

SELECT Field1, Field2 FROM SomeTable WHERE --(constraints)

Außerhalb der Datenbank besteht bei dynamischen Abfragen das Risiko von Injektionsangriffen und fehlerhaften Daten. In der Regel umgehen Sie dies mithilfe gespeicherter Prozeduren oder parametrisierter Abfragen. Außerdem muss der Server (obwohl nicht wirklich ein großes Problem) jedes Mal, wenn eine dynamische Abfrage ausgeführt wird, einen Ausführungsplan erstellen.


"Der Server muss jedes Mal, wenn eine dynamische Abfrage ausgeführt wird, einen Ausführungsplan erstellen", von dem ich annehme, dass er die Abfrage verlangsamt. Vielen Dank.
Ankur

Die Leistungsprobleme bei der Verwendung von dynamischem SQL würden wahrscheinlich nur in Szenarien mit sehr hoher Auslastung realisiert. SQL Server ist ziemlich gut darin, Abfragepläne effizient zu verwalten.
Matthew Abbott

2

Die Auswahl ist gleichermaßen effizient (in Bezug auf die Geschwindigkeit), wenn Sie * oder Spalten verwenden.

Der Unterschied liegt im Gedächtnis, nicht in der Geschwindigkeit. Wenn Sie mehrere Spalten auswählen, muss SQL Server Speicherplatz für die Abfrage zuweisen, einschließlich aller Daten für alle von Ihnen angeforderten Spalten, auch wenn Sie nur eine davon verwenden.

Was für die Leistung wichtig ist, ist der Ausführungsplan, der wiederum stark von Ihrer WHERE-Klausel und der Anzahl der JOIN, OUTER JOIN usw. abhängt.

Verwenden Sie für Ihre Frage einfach SELECT *. Wenn Sie alle Spalten benötigen, gibt es keinen Leistungsunterschied.


2

Es ist NICHT schneller, explizite Feldnamen im Vergleich zu * zu verwenden, wenn und nur dann, wenn Sie die Daten für alle Felder abrufen müssen.

Ihre Client-Software sollte nicht von der Reihenfolge der zurückgegebenen Felder abhängen, das ist also auch ein Unsinn.

Und es ist möglich (wenn auch unwahrscheinlich), dass Sie alle Felder mit * abrufen müssen, da Sie noch nicht wissen, welche Felder vorhanden sind (denken Sie an eine sehr dynamische Datenbankstruktur).

Ein weiterer Nachteil der Verwendung expliziter Feldnamen besteht darin, dass das Lesen des Codes und / oder des Abfrageprotokolls schwieriger wird, wenn viele davon vorhanden und lang sind.

Die Regel sollte also lauten: Wenn Sie alle Felder benötigen, verwenden Sie *. Wenn Sie nur eine Teilmenge benötigen, benennen Sie sie explizit.


2

Das Ergebnis ist zu groß. Es ist langsam, das Ergebnis von der SQL-Engine zu generieren und an den Client zu senden.

Die Client-Seite ist eine generische Programmierumgebung und sollte und sollte nicht zum Filtern und Verarbeiten der Ergebnisse (z. B. WHERE-Klausel, ORDER-Klausel) ausgelegt sein, da die Anzahl der Zeilen sehr groß sein kann (z. B. mehrere zehn Millionen Zeilen).


Wenn Sie also tatsächlich alle verschiedenen Spalten verwenden müssten, wäre das in Ordnung ... und wenn Ihre Datenbank und App wieder auf demselben Server sitzen, macht es keinen großen Unterschied?
Ankur

@Ankur: Selbst auf demselben Server fallen Kosten für die Übertragung von Daten über die Datenbankschnittstelle an.
Kennytm

2

Durch das Benennen jeder Spalte, die Sie in Ihrer Anwendung erwarten, wird auch sichergestellt, dass Ihre Anwendung nicht beschädigt wird, wenn jemand die Tabelle ändert, solange Ihre Spalten noch vorhanden sind (in beliebiger Reihenfolge).


1

Dies hängt von der Version Ihres DB-Servers ab, aber moderne Versionen von SQL können den Plan in beiden Fällen zwischenspeichern. Ich würde sagen, gehen Sie mit dem, was mit Ihrem Datenzugriffscode am wartbarsten ist.


1

Ein Grund, warum es besser ist, genau anzugeben, welche Spalten Sie möchten, sind mögliche zukünftige Änderungen in der Tabellenstruktur.

Wenn Sie Daten manuell mithilfe eines indexbasierten Ansatzes einlesen, um eine Datenstruktur mit den Ergebnissen Ihrer Abfrage zu füllen, werden Sie in Zukunft beim Hinzufügen / Entfernen einer Spalte Kopfschmerzen haben, um herauszufinden, was schief gelaufen ist.

Was schneller ist, werde ich anderen wegen ihres Fachwissens aufschieben.


1

Wie bei den meisten Problemen hängt es davon ab, was Sie erreichen möchten. Wenn Sie ein Datenbankraster erstellen möchten, das alle Spalten in einer Tabelle zulässt, ist "Select *" die Antwort. Wenn Sie jedoch nur bestimmte Spalten benötigen und das Hinzufügen oder Löschen von Spalten zur Abfrage nur selten erfolgt, geben Sie diese einzeln an.

Dies hängt auch von der Datenmenge ab, die Sie vom Server übertragen möchten. Wenn eine der Spalten als Memo, Grafik, Blob usw. definiert ist und Sie diese Spalte nicht benötigen, verwenden Sie besser nicht "Auswählen *", da Sie sonst eine ganze Reihe von Daten erhalten, die Sie nicht benötigen wollen und Ihre Leistung könnte leiden.


1

Wenn alle von Ihnen ausgewählten Spalten in einem Index enthalten sind, wird Ihre Ergebnismenge aus dem Index abgerufen, anstatt zusätzliche Daten aus SQL nachzuschlagen.


1

SELECT * ist erforderlich, wenn Metadaten wie die Anzahl der Spalten abgerufen werden sollen.


1

Was alle oben gesagt haben, plus:

Wenn Sie nach lesbarem, wartbarem Code streben, gehen Sie wie folgt vor:

SELECT foo, bar FROM Widgets;

ist sofort lesbar und zeigt Absicht. Wenn Sie diesen Anruf tätigen, wissen Sie, was Sie zurückbekommen. Wenn Widgets nur Foo- und Balkenspalten haben, bedeutet die Auswahl von *, dass Sie immer noch darüber nachdenken müssen, was Sie zurückerhalten, bestätigen, dass die Reihenfolge korrekt zugeordnet ist usw. Wenn Widgets jedoch mehr Spalten haben, Sie aber nur an Foo interessiert sind und bar, dann wird Ihr Code unordentlich, wenn Sie nach einem Platzhalter fragen und dann nur einen Teil der zurückgegebenen Daten verwenden.


1

Und denken Sie daran, wenn Sie per Definition einen inneren Join haben, benötigen Sie nicht alle Spalten, da die Daten in den Join-Spalten wiederholt werden.

Es ist nicht so, dass das Auflisten von Spalten im SQl-Server schwierig oder sogar zeitaufwändig ist. Sie ziehen sie einfach aus dem Objektbrowser (Sie können alles auf einmal erhalten, indem Sie aus den Wortspalten ziehen). Ein dauerhafter Leistungseinbruch auf Ihrem System (da dies die Verwendung von Indizes reduzieren kann und das Senden nicht benötigter Daten über das Netzwerk kostspielig ist) und die Wahrscheinlichkeit erhöhen, dass Sie unerwartete Probleme haben, wenn sich die Datenbank ändert (manchmal werden Spalten hinzugefügt) Sie möchten nicht, dass der Benutzer zum Beispiel sieht.) Nur weniger als eine Minute Entwicklungszeit zu sparen, ist kurzsichtig und unprofessionell.


1

In Bezug auf die Leistung habe ich Kommentare gesehen, dass beide gleich sind. Aber Usability-Aspekt gibt es einige + und s

Wenn Sie in einer Abfrage ein (select *) verwenden und jemand die Tabelle ändert und neue Felder hinzufügt, die für die vorherige Abfrage nicht benötigt werden, ist dies ein unnötiger Overhead. Und was ist, wenn das neu hinzugefügte Feld ein Blob oder ein Bildfeld ist? Ihre Antwortzeit auf Anfragen wird dann sehr langsam sein.

Wenn Sie dagegen a (select col1, col2, ..) verwenden und wenn die Tabelle geändert und neue Felder hinzugefügt werden und wenn diese Felder in der Ergebnismenge benötigt werden, müssen Sie Ihre select-Abfrage nach der Tabellenänderung immer bearbeiten.

Ich empfehle jedoch, in Ihren Abfragen immer select col1, col2, ... zu verwenden und die Abfrage zu ändern, wenn die Tabelle später geändert wird ...


0

Definieren Sie unbedingt die Spalten, die Sie jedes Mal auswählen möchten. Es gibt keinen Grund, dies nicht zu tun, und die Leistungsverbesserung ist es wert.

Sie hätten niemals die Option "SELECT *" geben dürfen.


0

Wenn Sie jede Spalte benötigen, verwenden Sie einfach SELECT *. Beachten Sie jedoch, dass sich die Reihenfolge möglicherweise ändern kann. Wenn Sie die Ergebnisse verbrauchen, greifen Sie nach Namen und nicht nach Index zu.

Ich würde Kommentare darüber ignorieren, wie * die Liste abrufen muss - die Wahrscheinlichkeit, dass benannte Spalten analysiert und validiert werden, entspricht der Verarbeitungszeit, wenn nicht mehr. Nicht vorzeitig optimieren ;-)


0

In Bezug auf die Ausführungseffizienz sind mir keine signifikanten Unterschiede bekannt. Aber für die Effizienz der Programmierer würde ich die Namen der Felder schreiben, weil

  • Sie kennen die Reihenfolge, wenn Sie nach Nummern indizieren müssen oder wenn sich Ihr Treiber bei Blob-Werten komisch verhält und Sie eine bestimmte Reihenfolge benötigen
  • Sie lesen nur die Felder, die Sie benötigen, wenn Sie jemals weitere Felder hinzufügen sollten
  • Sie erhalten einen SQL-Fehler, wenn Sie ein Feld falsch schreiben oder umbenennen, nicht einen leeren Wert aus einem Recordset / einer Zeile
  • Sie können besser lesen, was los ist.

0

Hey, sei praktisch. Verwenden Sie beim Prototyping select * und beim Implementieren und Bereitstellen bestimmte Spalten. Aus Sicht des Ausführungsplans sind beide auf modernen Systemen relativ identisch. Durch die Auswahl bestimmter Spalten wird jedoch die Datenmenge begrenzt, die von der Festplatte abgerufen, im Speicher gespeichert und über das Netzwerk gesendet werden muss.

Letztendlich ist es am besten, bestimmte Spalten auszuwählen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.