it-swarm-eu.dev

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

Das habe ich gehört SELECT * ist im Allgemeinen eine schlechte Praxis beim Schreiben von SQL-Befehlen, da es effizienter ist, SELECT -Spalten zu erstellen, die Sie speziell benötigen.

Wenn ich jede Spalte in einer Tabelle SELECT muss, sollte ich verwenden

SELECT * FROM TABLE

oder

SELECT column1, colum2, column3, etc. FROM TABLE

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

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

PDATE: Ich sollte wahrscheinlich angeben, dass die einzige Situation, in der ich wirklich möchte , dass ein 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.

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

155
Dan Herbert

Ein Grund für die bessere Auswahl bestimmter Spalten ist, dass dadurch 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

Es ist auch weniger anfällig, Änderungen vorzunehmen, da jeder Code, der die Daten verbraucht, die gleiche Datenstruktur erhält, unabhängig von den Änderungen, die Sie in Zukunft am Tabellenschema vornehmen.

158
Jon Galloway

Vorausgesetzt Ihre Angabe, dass Sie sind alle Spalten auswählen, gibt es wenig Unterschied zu diesem Zeitpunkt. Beachten Sie jedoch, dass sich Datenbankschemata ändern. Wenn du benutzt SELECT * Sie werden neue Spalten in die Tabelle aufnehmen, obwohl Ihr Code höchstwahrscheinlich nicht bereit ist, diese neuen Daten zu verwenden oder zu präsentieren. Dies bedeutet, dass Sie Ihr System unerwarteten Leistungs- und Funktionsänderungen aussetzen.

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

  1. Aus Datenbank lesen
  2. Wird ü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

Element Nr. 1 hat viele versteckte Kosten, einschließlich des Eliminierens eines potenziellen Deckungsindex, das Laden von Datenseiten (und das Überladen des Server-Cache) und das Entstehen von Zeilen-/Seiten-/Tabellensperren, die ansonsten vermieden werden könnten.

Vergleichen Sie dies mit den potenziellen Einsparungen bei der Angabe der Spalten im Vergleich zu einem * und die einzigen möglichen Einsparungen sind:

  1. Der Programmierer muss die SQL nicht erneut aufrufen, um Spalten hinzuzufügen
  2. Der Netzwerktransport der SQL ist kleiner/schneller
  3. SQL Server-Abfrage-/Überprüfungszeit
  4. SQL Server-Abfrageplan-Cache

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

Bei Punkt 2 reicht der Unterschied selten aus, um Sie in eine andere Paketgröße oder Anzahl von Netzwerkpaketen zu verschieben. Wenn Sie den Punkt erreichen, 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 von * muss sowieso passieren, was bedeutet, das Schema der Tabelle (n) trotzdem zu konsultieren. Realistisch gesehen verursacht das Auflisten der Spalten dieselben Kosten, da sie anhand des Schemas validiert werden müssen. Mit anderen Worten, dies ist eine komplette Wäsche.

Wenn Sie für Element 4 bestimmte Spalten angeben, wird der Cache Ihres Abfrageplans möglicherweise größer, aber nur, wenn Sie mit verschiedenen Spaltensätzen arbeiten (die nicht von Ihnen angegeben wurden). In diesem Fall möchten verschiedene Cache-Einträge, da Sie nach Bedarf verschiedene Pläne wünschen.

Das alles hängt also von der Art und Weise ab, wie Sie die Frage spezifiziert haben, von der Ausfallsicherheit des Problems angesichts eventueller Schemaänderungen. Wenn Sie dieses Schema in ROM (es passiert), dann ein * ist völlig akzeptabel.

Meine allgemeine Richtlinie lautet jedoch, dass Sie nur die Spalten auswählen sollten, die Sie benötigen. Dies bedeutet, dass manchmal Sie alle nachfragen, aber DBAs und Schemaentwicklungen bedeuten, dass einige neue Spalten möglicherweise vorhanden sind angezeigt, die die Abfrage stark beeinflussen könnten.

Mein Rat ist, dass Sie immer bestimmte Spalten auswählen. Denken Sie daran, dass Sie immer wieder gute Arbeit leisten, und gewöhnen Sie sich einfach an, es richtig zu machen.

Wenn Sie sich fragen, warum sich ein Schema ändern kann, ohne dass sich der Code ändert, sollten Sie die Überwachungsprotokollierung, die Gültigkeits-/Ablaufdaten und andere ähnliche Aspekte berücksichtigen, die DBAs systematisch für Compliance-Probleme hinzufügen. Eine weitere Ursache für unbeabsichtigte Änderungen sind Denormalisierungen für die Leistung an anderer Stelle im System oder in benutzerdefinierten Feldern.

57
IDisposable

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

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

Abgesehen davon, wenn die Tabelle eine binäre Spalte enthält, ist die Abfrage viel langsamer und beansprucht mehr Netzwerkressourcen.

33
Giorgi

Es gibt vier große Gründe, warum select * ist eine schlechte Sache:

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

  2. Wenn Sie einen Spaltennamen ändern, ist es besser, ihn frühzeitig (zum Zeitpunkt des SQL-Aufrufs) zu erfassen, 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 nicht benötigte Spalten nur Makulatur.

30
pkh

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

9
ilitirit

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

  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 DB-Schemas 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 Feld für website-verwalteten Inhalt in eine Tabelle einfügen und alle Vorteile des CMS (Versionierung, Workflow/Genehmigungen usw.) nutzen, während wir nur den Code an einer bestimmten Stelle berühren paar Punkte, anstatt 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.

7
Herb Caudill

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, was Zeit in Anspruch nimmt und das System unnötig belastet (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 optimieren, wie dies der Fall ist (verwenden Sie beispielsweise den abdeckenden Index für die Abfrage).
  2. Nach einiger Zeit kann sich Ihre Tabellenstruktur ändern, sodass SELECT * einen anderen Satz von Spalten zurückgibt. Daher kann Ihre Anwendung einen Datensatz mit unerwarteter Struktur erhalten und sich irgendwo stromabwärts auflösen. 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').

Für ein kleines und einfaches System ist das alles natürlich nicht so wichtig.

6
VladV

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 im Grunde genommen unbemerkt und nahezu zeitlich konstant. Eines Tages wird sich Ihr Schema ändern, und dies ist eine gute Versicherung, um diesbezügliche Probleme zu vermeiden.

4
Yann Ramin

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

Das explizite Benennen der Spalten hilft Ihnen bei der Wartung in der Zukunft. Irgendwann werden Sie Änderungen oder Fehlerbehebungen vornehmen und sich fragen: "Wo zum Teufel wird diese Spalte verwendet?".

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

4

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

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

Bei dynamischen Abfragen außerhalb der Datenbank besteht das Risiko von Injection-Angriffen und fehlerhaften Daten. In der Regel umgehen Sie dies mit gespeicherten Prozeduren oder parametrisierten Abfragen. Außerdem muss der Server jedes Mal, wenn eine dynamische Abfrage ausgeführt wird, einen Ausführungsplan erstellen (auch wenn dies nicht wirklich ein großes Problem darstellt).

4
Matthew Abbott

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

Selbst wenn Sie alle von einem "select * ..." mitgebrachten Spalten verwenden, ist dies erst einmal der Fall. Wenn Sie in Zukunft das Layout der Tabelle/Ansicht ändern und weitere Spalten hinzufügen, nehmen Sie diese in Ihre Auswahl auf, auch wenn Sie sie nicht benötigen.

Ein weiterer Punkt, an dem eine "select *" - Anweisung fehlerhaft ist, ist das Erstellen von Ansichten. Wenn Sie eine Ansicht mit "select *" erstellen und später Ihrer Tabelle Spalten 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 es verlockend ist, ein "select *" zu schreiben, da ich es wirklich nicht mag, alle Felder in meinen Abfragen manuell anzugeben, aber wenn sich Ihr System weiterentwickelt, werden Sie feststellen, dass es sich lohnt, diese zusätzliche Zeit zu verwenden/Aufwand beim Festlegen der Felder, anstatt viel mehr Zeit und Mühe damit zu verbringen, Fehler in Ihren Ansichten zu beseitigen oder Ihre App zu optimieren.

3

Während das explizite Auflisten von Spalten der Leistung zuträglich 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). Dann - messen. Vergleichen Sie mit Abfrage mit Spaltennamen, die explizit aufgeführt sind.

Spekulieren Sie nicht über Leistung, messen Sie es!

Eine explizite Auflistung ist am hilfreichsten, wenn Sie eine Spalte mit großen Datenmengen haben (z. B. den Text eines Posts oder Artikels) und diese in einer bestimmten Abfrage nicht benötigen. Wenn Sie es dann nicht in Ihrem Antwort-DB-Server zurückgeben, können Sie Zeit, Bandbreite und Datenträgerdurchsatz sparen. Ihr Abfrageergebnis wird auch kleiner sein, was für jeden Abfragecache gut ist.

3
Paweł Hajdan

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

3
Nick Berardi

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.

3
BrewinBombers

Select ist (in Bezug auf die Geschwindigkeit) gleichermaßen effizient, 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 zuweisen, damit die Abfrage ausgeführt werden kann, einschließlich aller Daten für alle von Ihnen angeforderten Spalten, auch wenn Sie nur eine von ihnen verwenden.

Was für die Leistung von Bedeutung ist, ist der Ausführungsplan, der wiederum stark von Ihrer WHERE-Klausel und der Anzahl von 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
Jorge Córdoba

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, die eine generische Programmierumgebung ist, ist nicht dafür ausgelegt und sollte nicht dafür ausgelegt sein, die Ergebnisse zu filtern und zu verarbeiten (z. B. die WHERE-Klausel, die ORDER-Klausel), da die Anzahl der Zeilen sehr groß sein kann (z. B. Dutzende Millionen Zeilen).

2
kennytm

Durch die Benennung 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).

2
Don

Es ist NICHT schneller, explizite Feldnamen im Vergleich zu * zu verwenden, 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, also ist das 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 erschwert wird, wenn viele von ihnen 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
user9385

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

1
Keith

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, wenn Sie herausfinden, was schief gelaufen ist.

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

1
dpollock

Und denken Sie daran, dass Sie bei einer inneren Verknüpfung per Definition nicht alle Spalten benötigen, da die Daten in den Verknüpfungsspalten wiederholt werden.

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

1
HLGEM

Was alle oben gesagt haben, plus:

Wenn Sie lesbaren, wartbaren Code anstreben, tun Sie Folgendes:

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 über Foo- und Balkenspalten verfügen, bedeutet die Auswahl von *, dass Sie sich noch Gedanken darüber machen müssen, was Sie zurückerhalten, bestätigen, dass die Reihenfolge korrekt zugeordnet ist usw. Wenn Widgets jedoch über mehr Spalten verfügen, sind Sie nur an Foo interessiert Wenn Sie nach einem Platzhalter fragen und dann nur einen Teil der zurückgegebenen Werte verwenden, wird Ihr Code unübersichtlich.

1
Faisal

SELECT * ist notwendig, wenn man Metadaten wie die Anzahl der Spalten erhalten möchte.

1
Mark Etable

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
Mike

Wie bei den meisten Problemen kommt es darauf an, was Sie erreichen wollen. Wenn Sie ein DB-Raster 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 aus der 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, sollten Sie "Select *" nicht verwenden, da Sie sonst eine ganze Reihe von Daten erhalten, die Sie nicht benötigen wollen und Ihre Leistung leiden könnte.

1
Mark

Ob die Effizienz entscheidend ist oder nicht, hängt stark von der Größe Ihrer Produktionsdatensätze (und deren Wachstumsrate) ab. Wenn Ihre Datasets nicht so groß sind und nicht so schnell wachsen, hat die Auswahl einzelner Spalten möglicherweise keinen großen Leistungsvorteil.

Mit größeren Datenmengen und schnellerem Datenwachstum wird der Leistungsvorteil immer wichtiger.

Um grafisch zu sehen, ob es einen Unterschied gibt oder nicht, würde ich vorschlagen, den Abfrageausführungsplan für ein SELECT * und die entsprechenden SELECT-Abfragen col1, col2 usw. mithilfe des Abfrageanalysators anzuzeigen. Damit sollten Sie feststellen, welche der beiden Abfragen effizienter ist. Sie können auch einige Testdaten mit unterschiedlichen Lautstärken generieren, um zu sehen, wie die Timings sind.

0
Scott Lawrence

Ich werde dafür aufgeschlagen, aber ich wähle * aus, weil fast alle meine Daten aus SQL Server-Ansichten abgerufen werden, die die erforderlichen Werte aus mehreren Tabellen in einer einzigen, leicht zugänglichen Ansicht vorkombinieren.

Ich möchte dann alle Spalten aus der Ansicht, die sich nicht ändern, wenn neue Felder zu den zugrunde liegenden Tabellen hinzugefügt werden. Dies hat den zusätzlichen Vorteil, dass ich ändern kann, woher die Daten stammen. FieldA in der Ansicht kann einmal berechnet werden und dann kann ich es ändern, um statisch zu sein. In jedem Fall liefert mir der View FieldA.

Das Schöne daran ist, dass es meiner Datenschicht ermöglicht, Datensätze abzurufen. Es übergibt sie dann an meine BL, die daraus Objekte erstellen kann. Meine Haupt-App kennt und interagiert nur mit den Objekten. Ich erlaube meinen Objekten sogar, sich selbst zu erstellen, wenn eine Datenzeile übergeben wird.

Natürlich bin ich der einzige Entwickler, das hilft auch :)

0
klkitchens

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 sollten niemals die Option "SELECT *" angegeben haben

0
cazlab

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 auf sie nach Namen und nicht nach Index zu.

Ich würde Kommentare darüber, wie * die Liste abrufen muss, ignorieren. Die Wahrscheinlichkeit, dass benannte Spalten analysiert werden, ist gleich der Verarbeitungszeit, wenn nicht sogar länger. Nicht vorzeitig optimieren ;-)

0
DamienG

Der Hauptunterschied zwischen den beiden besteht in der Menge der Daten, die hin und her übertragen werden. Alle Argumente zur Zeitdifferenz sind grundsätzlich dahingehend fehlerhaft, dass "select *" und "select col1, ..., colN" dieselbe Menge relativer Arbeit verursachen, die von der DB-Engine ausgeführt wird. Das Übertragen von 15 Spalten pro Zeile im Vergleich zu 5 Spalten pro Zeile ist jedoch ein Unterschied von 10 Spalten.

0
Jeff Hubbard

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

  • Sie kennen die Reihenfolge, wenn Sie nach Zahlen indizieren müssen oder wenn sich Ihr Fahrer in Bezug auf Blob-Werte lustig verhält und Sie eine bestimmte Reihenfolge benötigen
  • Sie lesen die benötigten Felder nur, wenn Sie jemals mehr Felder hinzufügen sollten
  • Sie erhalten eine SQL-Fehlermeldung, 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
Erik

Ich sehe, dass einige Leute denken, dass es viel länger dauert, die Spalten zu spezifizieren. Da Sie die Spaltenliste aus dem Objektbrowser ziehen können, dauert es möglicherweise eine zusätzliche Minute, um Spalten in der Abfrage anzugeben (wenn Sie viele Spalten haben und einige Zeit damit verbringen müssen, sie in separate Zeilen zu setzen). Warum denken die Leute, dass das so zeitaufwändig ist?

0
HLGEM

Ich empfehle immer, die benötigten Spalten anzugeben, falls sich Ihr Schema ändert und Sie keine zusätzliche Spalte benötigen.

Qualifizieren Sie außerdem die Spaltennamen mit dem Tabellennamen. Dies ist wichtig, wenn die Abfrage Verknüpfungen enthält. Ohne die Tabellenqualifikationen kann es schwierig sein, sich zu erinnern, welche Spalte aus welcher Tabelle stammt, und das Hinzufügen einer Spalte mit ähnlichem Namen zu einer der anderen Tabellen kann Ihre Abfrage beschädigen.

0
mxsscott

In Bezug auf die Leistung habe ich gesehen, dass beide gleich sind. Aber unter dem Gesichtspunkt der Benutzerfreundlichkeit gibt es einige Pluspunkte

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

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

Aber ich schlage vor, in Ihren Abfragen immer select col1, col2, ... zu verwenden und die Abfrage zu ändern, wenn die Tabelle später geändert wird ...

0
Lahiru Cooray

Für die Leistung ist es besonders wichtig, select * nicht zu verwenden, wenn Sie einen Join haben, da per Definition mindestens zwei Felder die gleichen Daten enthalten. Sie möchten keine Netzwerkressourcen verschwenden, indem Sie nicht benötigte Daten vom Datenbankserver an die Anwendung oder den Webserver senden. Es mag einfacher erscheinen, select * zu verwenden, aber es ist eine schlechte Praxis. Da es einfach ist, die Spaltennamen in die Abfrage zu ziehen, tun Sie dies stattdessen einfach.

Ein weiteres Problem, das bei der Verwendung von select * auftritt, besteht darin, dass es Idioten gibt, die neue Felder in der Tabellenmitte hinzufügen (was immer eine schlechte Praxis ist) Wenn Sie falsch liegen, können Sie versuchen, die Sozialversicherungsnummer in das Honorar einzufügen (die Summe der Gelder, die ein Redner für die Auswahl eines nicht zufälligen Beispiels erhält), was für die Datenintegrität eine sehr schlechte Sache sein kann. Auch wenn die Auswahl keine Beilage ist, sieht es für den Kunden schlecht aus, wenn die Daten plötzlich in der richtigen Reihenfolge auf dem Bericht oder der Webseite sind.

Ich denke, dass bei der Verwendung von select * kein Umstand der Verwendung einer Spaltenliste vorzuziehen ist. Sie denken vielleicht, es ist einfacher zu pflegen, aber in Wahrheit ist dies nicht der Fall und führt dazu, dass Ihre Anwendung ohne Grund langsamer wird, wenn Felder, die Sie nicht benötigen, zu den Tabellen hinzugefügt werden. Sie müssen sich auch mit dem Problem auseinandersetzen, Dinge zu reparieren, die nicht kaputt gegangen wären, wenn Sie eine Spaltenliste verwendet hätten. Daher wird die Zeit, die Sie sparen, wenn Sie keine Spalte hinzufügen, auf diese Weise aufgebraucht.

0
HLGEM

hey, sei praktisch. Verwenden Sie select * beim Prototyping und wählen Sie bestimmte Spalten beim Implementieren und Bereitstellen aus. 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.

0
siculars

Denken Sie auch an Änderungen. Heute wählt Select * nur die Spalten aus, die Sie benötigen, aber morgen wird möglicherweise auch die varbinäre Spalte (MAX) ausgewählt, die ich gerade hinzugefügt habe, ohne Sie darüber zu informieren, und Sie erhalten jetzt auch alle 3,18 Gigabyte Binärdaten, die nicht vorhanden waren in der Tabelle gestern.

0
Michael Stum

Überlegen wir, was schneller ist. Wenn Sie nur die Daten auswählen können, die Sie benötigen, sind sie schneller. Beim Testen können Sie jedoch alle Daten abrufen, um zu beurteilen, welche Daten basierend auf den Geschäftsanforderungen herausgefiltert werden können.

0
mikedopp

Es gibt Fälle, in denen SELECT * für Wartungszwecke geeignet ist, dies sollte jedoch im Allgemeinen vermieden werden.

Hierbei handelt es sich um Sonderfälle wie Ansichten oder gespeicherte Prozeduren, in denen Änderungen in zugrunde liegenden Tabellen übernommen werden sollen, ohne dass jede Ansicht und jeder gespeicherte Prozess, der die Tabelle verwendet, geändert werden muss. Dies kann selbst dann zu Problemen führen, z. B. wenn zwei Ansichten verbunden sind. Eine zugrunde liegende Tabelle ändert sich und die Ansicht ist jetzt mehrdeutig, da beide Tabellen eine Spalte mit demselben Namen haben. (Beachten Sie, dass dies immer dann vorkommen kann, wenn Sie nicht alle Spalten mit Tabellenpräfixen qualifizieren.) Auch mit Präfixen, wenn Sie ein Konstrukt haben wie:

SELECT A ., B. - Sie können Probleme haben, wenn der Client jetzt Schwierigkeiten hat, das richtige Feld auszuwählen.

Im Allgemeinen verwende ich SELECT * nur, wenn ich eine bewusste Entwurfsentscheidung treffe und davon ausgehe, dass die damit verbundenen Risiken gering sind.

0
Cade Roux

Das SELECT *könnte sein ist in Ordnung, wenn Sie tatsächlich alle Spalten benötigt haben - aber Sie sollten sie trotzdem alle einzeln auflisten. Sie sollten auf keinen Fall alle Zeilen aus einer Tabelle auswählen - auch wenn sich die App und die Datenbank auf demselben Server oder im selben Netzwerk befinden. Das Übertragen aller Zeilen nimmt Zeit in Anspruch, insbesondere wenn die Anzahl der Zeilen zunimmt. Sie sollten mindestens eine where-Klausel haben, die die Ergebnisse filtert und/oder die Ergebnisse anzeigt, um nur die Teilmenge der Zeilen auszuwählen, die angezeigt werden sollen. Abhängig von der von Ihnen verwendeten App-Sprache gibt es verschiedene ORM-Tools, die Sie beim Abfragen und Durchsuchen der von Ihnen benötigten Teilmenge von Daten unterstützen. In .NET Linq to SQL helfen Ihnen beispielsweise Entity Framework und nHibernate dabei.

0
bkaid

Verwenden Sie bestimmte Feldnamen. Wenn also jemand die Tabelle für Sie ändert, erhalten Sie keine unerwarteten Ergebnisse. Zu diesem Thema: Geben Sie beim Einfügen IMMER Feldnamen an. Wenn Sie also später eine Spalte hinzufügen müssen, müssen Sie nicht zurückgehen und Ihr Programm reparieren und gleichzeitig die Datenbank in der Produktionsversion ändern.

0
stu

Wenn Sie sich mit Geschwindigkeit beschäftigen, stellen Sie sicher, dass Sie vorbereitete Anweisungen verwenden. Ansonsten bin ich mit ilitirit, dass Änderungen das sind, wovor Sie sich schützen.

/ Allan

0
Allan Wind

Das Auflisten von Spaltennamen ist besonders wichtig, wenn andere Entwickler wahrscheinlich mit dem Code arbeiten oder wenn sich die Datenbank wahrscheinlich ändert, sodass Sie immer konsistente Daten erhalten.

0
Sam Cogan

Dies ist ein alter Beitrag, aber immer noch gültig. Als Referenz habe ich eine sehr komplizierte Abfrage bestehend aus:

  • 12 Tische
  • 6 Linke Joins
  • 9 innere Verbindungen
  • Insgesamt 108 Spalten in allen 12 Tabellen
  • Ich brauche nur 54 Spalten
  • Eine 4-spaltige Order By-Klausel

Wenn ich die Abfrage mit Select * ausführe, dauert es durchschnittlich 2869 ms. Wenn ich die Abfrage mit Select ausführe, dauert es durchschnittlich 1513ms.

Die Gesamtzahl der zurückgegebenen Zeilen beträgt 13.949.

Es besteht kein Zweifel, dass die Auswahl von Spaltennamen eine schnellere Leistung gegenüber Select * bedeutet.

Wenn Sie die Datenbank direkt abfragen möchten (z. B. an einer sqlplus-Eingabeaufforderung oder über ein DB-Verwaltungstool), ist die Auswahl von * im Allgemeinen in Ordnung - Sie müssen nicht alle Spalten ausschreiben.

Andererseits ist es im Anwendungscode am besten, die Spalten aufzulisten. Dies hat mehrere Vorteile:

  • Der Code ist klarer
  • Sie kennen die Reihenfolge, in der die Ergebnisse wieder angezeigt werden (dies kann für Sie wichtig sein oder auch nicht).
0
Morikal

Nun, es hängt wirklich von Ihren Metriken und Ihrem Zweck ab:

  1. Wenn Sie 250 Spalten haben und (tatsächlich) alle auswählen möchten, verwenden Sie select *, wenn Sie am selben Tag nach Hause kommen möchten :)
  2. Wenn Ihre Codierung Flexibilität erfordert und die benötigte Tabelle klein ist, hilft Ihnen select *, schneller zu codieren und sie einfacher zu pflegen.
  3. Wenn Sie eine robuste Technik und Leistung wünschen:
    • schreiben Sie Ihre Spaltennamen, wenn sie nur wenige sind, oder
    • schreiben Sie ein Tool, mit dem Sie Ihre Spaltennamen einfach auswählen und generieren können

Als Faustregel würde ich, wenn ich alle Spalten auswählen muss, "select *" verwenden, es sei denn, ich habe einen ganz bestimmten Grund, etwas anderes zu tun.

Und last but not least, wie soll sich das Hinzufügen oder Löschen einer Spalte in der Tabelle auf Ihren Code oder dessen Wartung auswirken?

0
Notitze