Warum wird SELECT * als schädlich angesehen?

256

Warum ist SELECT *schlechte Praxis? Würde es nicht bedeuten, dass weniger Code geändert werden muss, wenn Sie eine neue Spalte hinzufügen, die Sie möchten?

Ich verstehe, dass dies SELECT COUNT(*)bei einigen DBs ein Leistungsproblem ist, aber was ist, wenn Sie wirklich jede Spalte wollen?

Theodore R. Smith
quelle
30
SELECT COUNT(*)schlecht zu sein ist unglaublich alt und veraltet . Für Informationen über SELECT *- siehe: stackoverflow.com/questions/1960036/…
OMG Ponies
8
SELECT COUNT(*)gibt eine andere Antwort als, es SELECT COUNT(SomeColumn)sei denn, die Spalte ist eine NOT NULL-Spalte. Und der Optimierer kann eine SELECT COUNT(*)spezielle Behandlung geben - und das normalerweise auch. Beachten Sie auch, dass WHERE EXISTS(SELECT * FROM SomeTable WHERE ...)eine Sonderfallbehandlung erfolgt.
Jonathan Leffler
3
@ Michael Mrozek, eigentlich ist es das Gegenteil der Frage. Ich frage, ob es jemals schädlich war, nicht, ob es jemals nicht schädlich war.
Theodore R. Smith
1
@Bytecode Ninja: Insbesondere hat MySQL mit MyISAM-Engine eine Optimierung für COUNT (*): mysqlperformanceblog.com/2007/04/10/count-vs-countcol
Piskvor verließ das Gebäude
1
Für SQL Server siehe sqlblog.com/blogs/aaron_bertrand/archive/2009/10/10/…
Aaron Bertrand

Antworten:

312

Es gibt wirklich drei Hauptgründe:

  • Ineffizienz beim Verschieben von Daten zum Verbraucher. Wenn Sie SELECT * auswählen, rufen Sie häufig mehr Spalten aus der Datenbank ab, als Ihre Anwendung wirklich benötigt, um zu funktionieren. Dies führt dazu, dass mehr Daten vom Datenbankserver auf den Client übertragen werden, wodurch der Zugriff verlangsamt und die Belastung Ihrer Computer erhöht wird. Außerdem wird mehr Zeit für die Übertragung über das Netzwerk benötigt. Dies gilt insbesondere dann, wenn jemand zugrunde liegenden Tabellen neue Spalten hinzufügt, die nicht vorhanden waren und nicht benötigt wurden, als die ursprünglichen Verbraucher ihren Datenzugriff codierten.

  • Indizierungsprobleme. Stellen Sie sich ein Szenario vor, in dem Sie eine Abfrage auf ein hohes Leistungsniveau einstellen möchten. Wenn Sie * verwenden und mehr Spalten zurückgeben, als Sie tatsächlich benötigen, muss der Server häufig teurere Methoden zum Abrufen Ihrer Daten ausführen, als dies sonst der Fall wäre. Zum Beispiel könnten Sie keinen Index erstellen, der einfach die Spalten in Ihrer SELECT-Liste abdeckt, und selbst wenn Sie dies tun würden (einschließlich aller Spalten [ Schauder ]), der nächste, der vorbeikam und dem zugrunde liegenden eine Spalte hinzufügte Eine Tabelle würde dazu führen, dass das Optimierungsprogramm Ihren optimierten Abdeckungsindex ignoriert, und Sie würden wahrscheinlich feststellen, dass die Leistung Ihrer Abfrage ohne ersichtlichen Grund erheblich sinken würde.

  • Bindungsprobleme. Wenn Sie SELECT * auswählen, können Sie zwei gleichnamige Spalten aus zwei verschiedenen Tabellen abrufen. Dies kann Ihren Datenkonsumenten oft zum Absturz bringen. Stellen Sie sich eine Abfrage vor, die zwei Tabellen verbindet, die beide eine Spalte mit dem Namen "ID" enthalten. Wie würde ein Verbraucher wissen, welches welches war? SELECT * kann auch Ansichten verwirren (zumindest in einigen Versionen von SQL Server), wenn sich die zugrunde liegenden Tabellenstrukturen ändern - die Ansicht wird nicht neu erstellt, und die Daten, die zurückkommen, können Unsinn sein . Und das Schlimmste daran ist, dass Sie darauf achten können, Ihre Spalten so zu benennen, wie Sie möchten, aber der nächste, der mitkommt, kann möglicherweise nicht wissen, dass er sich Sorgen machen muss, eine Spalte hinzuzufügen, die mit Ihrer bereits entwickelten kollidiert Namen.

Aber es ist nicht alles schlecht für SELECT *. Ich benutze es großzügig für diese Anwendungsfälle:

  • Ad-hoc-Abfragen. Wenn ich versuche, etwas zu debuggen, insbesondere von einer schmalen Tabelle, mit der ich vielleicht nicht vertraut bin, ist SELECT * oft mein bester Freund. Es hilft mir nur zu sehen, was los ist, ohne eine Menge Nachforschungen anstellen zu müssen, wie die zugrunde liegenden Spaltennamen lauten. Dies wird ein größeres "Plus", je länger die Spaltennamen werden.

  • Wenn * "eine Zeile" bedeutet. In den folgenden Anwendungsfällen ist SELECT * in Ordnung, und Gerüchte, dass es sich um einen Performance-Killer handelt, sind nur urbane Legenden, die vor vielen Jahren eine gewisse Gültigkeit hatten, aber jetzt nicht:

    SELECT COUNT(*) FROM table;

    In diesem Fall bedeutet * "Zeilen zählen". Wenn Sie anstelle von * einen Spaltennamen verwenden, werden die Zeilen gezählt, in denen der Wert dieser Spalte nicht null war . COUNT (*) bringt für mich das Konzept, dass Sie Zeilen zählen , auf den Punkt und vermeidet seltsame Randfälle, die dadurch verursacht werden, dass NULL-Werte aus Ihren Aggregaten entfernt werden.

    Gleiches gilt für diese Art von Abfrage:

    SELECT a.ID FROM TableA a
    WHERE EXISTS (
        SELECT *
        FROM TableB b
        WHERE b.ID = a.B_ID);

    In jeder Datenbank, die ihr Geld wert ist, bedeutet * nur "eine Zeile". Es spielt keine Rolle, was Sie in die Unterabfrage eingeben. Einige Leute verwenden die ID von b in der SELECT-Liste, oder sie verwenden die Nummer 1, aber IMO sind diese Konventionen ziemlich unsinnig. Was Sie meinen, ist "Zählen Sie die Zeile", und das bedeutet *. Die meisten Abfrageoptimierer da draußen sind klug genug, dies zu wissen. (Um ehrlich zu sein, weiß ich nur , dass dies bei SQL Server und Oracle der Fall ist.)

Dave Markle
quelle
17
Bei Verwendung von "SELECT id, name" werden bei Verwendung von Joins mit gleicher Wahrscheinlichkeit wie bei "SELECT *" zwei gleichnamige Spalten aus zwei verschiedenen Tabellen ausgewählt. Das Präfixieren des Tabellennamens löst das Problem in beiden Fällen.
Michał Tatarynowicz
1
Ich weiß, dass dies älter ist, aber es ist das, was beim Googeln hochgezogen wurde, also frage ich. "Wenn *" eine Reihe "bedeutet. In den folgenden Anwendungsfällen ist SELECT * in Ordnung, und Gerüchte, dass es sich um einen Performance-Killer handelt, sind nur urbane Legenden ..." Haben Sie hier Referenzen? Liegt diese Aussage daran, dass die Hardware leistungsfähiger ist (wenn dies der Fall ist, bedeutet dies nicht, dass es nicht ineffizient ist, nur dass Sie es weniger wahrscheinlich bemerken). Ich versuche nicht, per se zu raten. Ich frage mich nur, woher diese Aussage kommt.
Jared
6
In Bezug auf Referenzen können Sie die Abfragepläne untersuchen. Sie sind in Fällen identisch, in denen die Unterabfrage ein "*" enthält, und wenn Sie eine Spalte auswählen. Sie sind identisch, da der kostenbasierte Optimierer semantisch "erkennt", dass es sich um eine Zeile handelt, die die Kriterien erfüllt - es geht nicht um Hardware oder Geschwindigkeit.
Dave Markle
4
Ein weiterer Vorteil der Verwendung *besteht darin, dass in einigen Situationen die Cache-Systeme von MySQL besser genutzt werden können. Wenn Sie eine große Anzahl ähnlicher selectAbfragen ausführen, die unterschiedliche Spaltennamen (,, ...) mit a anfordern select A where X, select B where Xkann select * where Xder Cache eine größere Anzahl von Abfragen verarbeiten, was zu einer erheblichen Leistungssteigerung führen kann. Es ist ein anwendungsspezifisches Szenario, aber es lohnt sich, daran zu denken.
Ben D
2
8+ Jahre später, möchte aber einen Punkt über Mehrdeutigkeit hinzufügen, der nicht erwähnt wurde. Arbeiten mit mehr als 200 Tabellen in einer Datenbank und mit einer Mischung aus Namenskonventionen. Wenn Sie Code überprüfen, der mit Abfrageergebnissen interagiert, müssen SELECT *Entwickler die beteiligten Tabellenschemata überprüfen , um die betroffenen / verfügbaren Spalten zu ermitteln, z. B. innerhalb eines foreachoder serialize. Die Aufgabe, wiederholt nach Schemas zu suchen, um festzustellen, was gerade passiert, erhöht zwangsläufig die Gesamtzeit, die sowohl für das Debuggen als auch für die Entwicklung von zugehörigem Code erforderlich ist.
Fyrye
91

Das Sternchen "*" in der SELECT-Anweisung steht für alle Spalten in den Tabellen, die an der Abfrage beteiligt sind.

Performance

Die *Kurzschrift kann langsamer sein, weil:

  • Nicht alle Felder sind indiziert, was einen vollständigen Tabellenscan erzwingt - weniger effizient
  • Was Sie speichern, um SELECT *über das Kabel zu senden , riskiert einen vollständigen Tabellenscan
  • Rückgabe von mehr Daten als erforderlich
  • Das Zurückgeben nachfolgender Spalten mit dem Datentyp variabler Länge kann zu Suchaufwand führen

Instandhaltung

Bei Verwendung von SELECT *:

  • Jemand, der mit der Codebasis nicht vertraut ist, muss die Dokumentation konsultieren, um zu erfahren, welche Spalten zurückgegeben werden, bevor er kompetente Änderungen vornehmen kann. Wenn Sie den Code besser lesbar machen, die Mehrdeutigkeit und die Arbeit minimieren, die für Personen erforderlich sind, die mit dem Code nicht vertraut sind, sparen Sie auf lange Sicht mehr Zeit und Mühe.
  • Wenn der Code von der Spaltenreihenfolge abhängt, SELECT *wird ein Fehler ausgeblendet, der darauf wartet, dass er auftritt, wenn die Spaltenreihenfolge einer Tabelle geändert wurde.
  • Selbst wenn Sie zum Zeitpunkt des Schreibens der Abfrage jede Spalte benötigen, ist dies in Zukunft möglicherweise nicht mehr der Fall
  • Die Verwendung erschwert die Profilerstellung

Design

SELECT *ist ein Anti-Muster :

  • Der Zweck der Abfrage ist weniger offensichtlich. Die von der Anwendung verwendeten Spalten sind undurchsichtig
  • Es verstößt gegen die Modularitätsregel, wenn immer möglich, strikt zu tippen. Explizit ist fast überall besser.

Wann sollte "SELECT *" verwendet werden?

Es ist akzeptabel, SELECT *wenn jede Spalte in den beteiligten Tabellen explizit benötigt wird, im Gegensatz zu jeder Spalte, die beim Schreiben der Abfrage vorhanden war. Die Datenbank erweitert das * intern in die vollständige Liste der Spalten - es gibt keinen Leistungsunterschied.

Andernfalls listen Sie explizit jede Spalte auf, die in der Abfrage verwendet werden soll - vorzugsweise unter Verwendung eines Tabellenalias.

OMG Ponys
quelle
20

Selbst wenn Sie jetzt jede Spalte auswählen möchten, möchten Sie möglicherweise nicht jede Spalte auswählen, nachdem jemand eine oder mehrere neue Spalten hinzugefügt hat. Wenn Sie die Abfrage mit Ihnen schreiben, gehen SELECT *Sie das Risiko ein, dass irgendwann jemand eine Textspalte hinzufügt, wodurch Ihre Abfrage langsamer ausgeführt wird, obwohl Sie diese Spalte tatsächlich nicht benötigen.

Würde es nicht bedeuten, weniger Code zu ändern, wenn Sie eine neue Spalte hinzufügen, die Sie möchten?

Wenn Sie die neue Spalte tatsächlich verwenden möchten, müssen Sie wahrscheinlich ohnehin noch viele andere Änderungen an Ihrem Code vornehmen. Sie sparen nur , new_column- nur ein paar Zeichen beim Tippen.

Mark Byers
quelle
21
Besonders wenn diese neue Spalte ein Drei-Megabyte-BLOB ist
Matti Virkkunen
2
@ Matti - Aber hoffentlich würden sie mehr darüber nachdenken als "Hey, lass uns eine riesige BLOB-Spalte auf diesen Tisch plumpsen!" . (Ja, ein Narr hofft, ich weiß, aber kann ein Kerl nicht träumen?)
ChaosPandion
5
Leistung ist ein Aspekt, aber oft gibt es auch einen Aspekt der Korrektheit: Die Form des projizierten Ergebnisses *kann sich unerwartet ändern und dies kann in der Anwendung selbst zu Chaos führen: Spalten, auf die durch Ordnungszahlen verwiesen wird (z. B. sqldatareader.getstring (2)), werden plötzlich abgerufen eine andere Spalte, jede INSERT ... SELECT *wird brechen und so weiter und so fort.
Remus Rusanu
2
@chaos: Blobs auf Tische zu setzen wird Ihre Leistung nicht wirklich beeinträchtigen ... Es sei denn, Sie verwenden SELECT * ... ;-)
Dave Markle
2
Sie sollten sich keine Sorgen um die Leistung machen, bis dies zu echten Problemen führt. Außerdem geht SELECT *es nicht darum, wenige Zeichen zu speichern. Es geht darum, Stunden an Debugging-Zeit zu sparen, da leicht vergessen wird, neu hinzugefügte Spalten anzugeben.
Lewis
4

Wenn Sie die Spalten in einer SELECT-Anweisung benennen, werden sie in der angegebenen Reihenfolge zurückgegeben und können daher sicher durch einen numerischen Index referenziert werden. Wenn Sie "SELECT *" verwenden, erhalten Sie die Spalten möglicherweise in beliebiger Reihenfolge und können die Spalten daher nur sicher nach Namen verwenden. Wenn Sie nicht im Voraus wissen, was Sie mit einer neuen Spalte tun möchten, die der Datenbank hinzugefügt wird, ist es am wahrscheinlichsten, sie zu ignorieren. Wenn Sie neue Spalten ignorieren, die der Datenbank hinzugefügt werden, hat das Abrufen keinerlei Vorteile.

Superkatze
quelle
"kann also sicher durch einen numerischen Index referenziert werden", aber wer wäre dumm genug, jemals zu versuchen, eine Spalte durch einen numerischen Index anstelle ihres Namens zu referenzieren? Das ist ein viel schlechteres Anti-Pattern als die Verwendung von select * in einer Ansicht.
MGOwen
@MGOwen: Das Verwenden select *und anschließende Verwenden der Spalten nach Index wäre schrecklich, aber das Verwenden select X, Y, Zoder select A,B,CÜbergeben des resultierenden Datenlesegeräts an Code, der erwartet, dass mit den Daten in den Spalten 0, 1 und 2 etwas zu tun ist, scheint ein durchaus vernünftiger Weg zu sein Lassen Sie denselben Code entweder auf X, Y, Z oder A, B, C einwirken. Beachten Sie, dass die Indizes von Spalten eher von ihrer Position in der SELECT-Anweisung als von ihrer Reihenfolge in der Datenbank abhängen.
Supercat
3

In vielen Situationen verursacht SELECT * Fehler zur Laufzeit in Ihrer Anwendung und nicht zur Entwurfszeit. Es verbirgt das Wissen über Spaltenänderungen oder fehlerhafte Referenzen in Ihren Anwendungen.

Andrew Lewis
quelle
1
Wie hilft die Benennung der Spalten? In SQL Server werden vorhandene Abfragen, die in Code oder SPs eingebettet sind, erst dann beanstandet, wenn sie ausgeführt werden, selbst wenn Sie die Spalten benannt haben. Neue werden fehlschlagen, wenn Sie sie testen, aber Sie müssen viel Zeit damit verbringen, nach SPs zu suchen, die von Tabellenänderungen betroffen sind. Auf welche Situationen beziehen Sie sich, die zur Entwurfszeit auftreten würden?
ChrisA
3

Wenn Sie wirklich jede Spalte möchten, habe ich keinen Leistungsunterschied zwischen select (*) und der Benennung der Spalten festgestellt. Der Treiber zum Benennen der Spalten kann einfach darin bestehen, explizit anzugeben, welche Spalten in Ihrem Code erwartet werden.

Oft möchten Sie jedoch nicht jede Spalte, und die Auswahl (*) kann zu unnötiger Arbeit für den Datenbankserver führen und dazu, dass unnötige Informationen über das Netzwerk übertragen werden müssen. Es ist unwahrscheinlich, dass ein erkennbares Problem auftritt, wenn das System nicht stark ausgelastet ist oder die Netzwerkverbindung langsam ist.

Brabster
quelle
3

Stellen Sie sich vor, Sie reduzieren die Kopplung zwischen der App und der Datenbank.

Um den Aspekt "Codegeruch" zusammenzufassen:
SELECT *Erstellt eine dynamische Abhängigkeit zwischen der App und dem Schema. Die Einschränkung der Verwendung ist eine Möglichkeit, die Abhängigkeit genauer zu definieren. Andernfalls besteht bei einer Änderung der Datenbank eine höhere Wahrscheinlichkeit, dass Ihre Anwendung abstürzt.

Kelly S. Französisch
quelle
3

Wenn Sie der Tabelle Felder hinzufügen, werden diese automatisch in alle Ihre Abfragen aufgenommen, die Sie verwenden select *. Dies mag praktisch erscheinen, führt jedoch dazu, dass Ihre Anwendung langsamer wird, da Sie mehr Daten abrufen, als Sie benötigen, und Ihre Anwendung tatsächlich irgendwann abstürzt.

Die Anzahl der Daten, die Sie in jeder Zeile eines Ergebnisses abrufen können, ist begrenzt. Wenn Sie Ihren Tabellen Felder hinzufügen, sodass ein Ergebnis diese Grenze überschreitet, wird beim Versuch, die Abfrage auszuführen, eine Fehlermeldung angezeigt.

Dies ist die Art von Fehlern, die schwer zu finden sind. Sie nehmen an einer Stelle eine Änderung vor, die an einer anderen Stelle explodiert, an der die neuen Daten überhaupt nicht verwendet werden. Es kann sogar eine weniger häufig verwendete Abfrage sein, so dass es eine Weile dauert, bis jemand sie verwendet, was es noch schwieriger macht, den Fehler mit der Änderung zu verbinden.

Wenn Sie angeben, welche Felder im Ergebnis angezeigt werden sollen, sind Sie vor einem solchen Overhead-Überlauf geschützt.

Guffa
quelle
2

Referenz aus diesem Artikel.

Gehen Sie niemals mit "SELECT *",

Ich habe nur einen Grund gefunden, "SELECT *" zu verwenden.

Wenn Sie spezielle Anforderungen haben und beim Hinzufügen oder Löschen eine dynamische Umgebung erstellt haben, wird die Spalte automatisch nach Anwendungscode behandelt. In diesem speziellen Fall müssen Sie den Anwendungs- und Datenbankcode nicht ändern. Dies wirkt sich automatisch auf die Produktionsumgebung aus. In diesem Fall können Sie "SELECT *" verwenden.

Anvesh
quelle
1

Im Allgemeinen müssen Sie die Ergebnisse SELECT * ...in Datenstrukturen verschiedener Typen einpassen. Ohne Angabe der Reihenfolge, in der die Ergebnisse eingehen, kann es schwierig sein, alles richtig auszurichten (und dunkelere Felder sind viel leichter zu übersehen).

Auf diese Weise können Sie Ihren Tabellen aus verschiedenen Gründen Felder hinzufügen (auch in der Mitte), ohne den SQL-Zugriffscode in der gesamten Anwendung zu beschädigen.

jkerian
quelle
1

Verwenden , SELECT *wenn Sie nur ein paar Spalten brauchen viel mehr Daten übertragen bedeutet , als Sie benötigen. Dies erhöht die Verarbeitung in der Datenbank und erhöht die Latenz beim Abrufen der Daten zum Client. Hinzu kommt, dass beim Laden mehr Speicher benötigt wird, in einigen Fällen deutlich mehr, z. B. bei großen BLOB-Dateien. Es geht hauptsächlich um Effizienz.

Darüber hinaus ist es jedoch einfacher, bei der Betrachtung der Abfrage zu erkennen, welche Spalten geladen werden, ohne nachschlagen zu müssen, was in der Tabelle enthalten ist.

Ja, wenn Sie eine zusätzliche Spalte hinzufügen, ist dies schneller, aber in den meisten Fällen möchten / müssen Sie Ihren Code mithilfe der Abfrage ändern, um die neuen Spalten trotzdem zu akzeptieren, und es besteht das Potenzial, dass Sie diejenigen erhalten, die Sie nicht verwenden. Nicht wollen / erwarten kann Probleme verursachen. Wenn Sie beispielsweise alle Spalten abrufen und sich dann auf die Reihenfolge in einer Schleife verlassen, um Variablen zuzuweisen, und dann eine hinzufügen, oder wenn sich die Spaltenreihenfolgen ändern (dies tritt beim Wiederherstellen aus einer Sicherung auf), kann dies alles abwerfen.

Dies ist auch die gleiche Art von Argumentation, warum Sie, wenn Sie eine machen INSERT, immer die Spalten angeben sollten.

Tarka
quelle
1

Ich glaube nicht, dass es dafür wirklich eine pauschale Regel geben kann. In vielen Fällen habe ich SELECT * vermieden, aber ich habe auch mit Datenframeworks gearbeitet, bei denen SELECT * sehr vorteilhaft war.

Wie bei allen Dingen gibt es Vorteile und Kosten. Ich denke, dass ein Teil der Nutzen-Kosten-Gleichung darin besteht, wie viel Kontrolle Sie über die Datenstrukturen haben. In Fällen, in denen SELECT * gut funktionierte, wurden die Datenstrukturen streng kontrolliert (es handelte sich um Einzelhandelssoftware), sodass nicht das große Risiko bestand, dass jemand ein riesiges BLOB-Feld in eine Tabelle schob.

JMarsch
quelle
1

Durch Auswahl mit Spaltennamen wird die Wahrscheinlichkeit erhöht, dass das Datenbankmodul über Indizes auf die Daten zugreifen kann, anstatt die Tabellendaten abzufragen.

SELECT * setzt Ihr System unerwarteten Leistungs- und Funktionsänderungen aus, wenn sich Ihr Datenbankschema ändert, da der Tabelle neue Spalten hinzugefügt werden, obwohl Ihr Code nicht bereit ist, diese neuen Daten zu verwenden oder zu präsentieren.

Aradhana Mohanty
quelle
1

Es gibt auch einen pragmatischeren Grund: Geld. Wenn Sie eine Cloud-Datenbank verwenden und für verarbeitete Daten bezahlen müssen, gibt es keine Erklärung für das Lesen von Daten, die Sie sofort verwerfen.

Zum Beispiel: BigQuery :

Preise abfragen

Die Abfragepreise beziehen sich auf die Kosten für die Ausführung Ihrer SQL-Befehle und benutzerdefinierten Funktionen. BigQuery berechnet für Abfragen eine Metrik: die Anzahl der verarbeiteten Bytes.

und Kontrollprojektion - Vermeiden Sie SELECT * :

Best Practice: Projektion steuern - Fragen Sie nur die Spalten ab, die Sie benötigen.

Projektion bezieht sich auf die Anzahl der Spalten, die von Ihrer Abfrage gelesen werden. Das Projizieren überschüssiger Spalten verursacht zusätzliche (verschwendete) E / A und Materialisierung (Schreibergebnisse).

Die Verwendung von SELECT * ist die teuerste Methode zum Abfragen von Daten. Wenn Sie SELECT * verwenden, führt BigQuery einen vollständigen Scan aller Spalten in der Tabelle durch.

Lukasz Szozda
quelle
0

Verstehen Sie Ihre Anforderungen, bevor Sie das Schema entwerfen (falls möglich).

Erfahren Sie mehr über die Daten, 1) Indizierung 2) Art des verwendeten Speichers, 3) Vendor Engine oder Funktionen; dh ... Caching, In-Memory-Funktionen 4) Datentypen 5) Größe der Tabelle 6) Häufigkeit der Abfrage 7) zugehörige Workloads, wenn die Ressource gemeinsam genutzt wird 8) Test

A) Die Anforderungen variieren. Wenn die Hardware die erwartete Arbeitslast nicht unterstützen kann, sollten Sie neu bewerten, wie die Anforderungen in der Arbeitslast bereitgestellt werden. Bezüglich der Additionsspalte zur Tabelle. Wenn die Datenbank Ansichten unterstützt, können Sie eine indizierte (?) Ansicht der spezifischen Daten mit den spezifischen benannten Spalten erstellen (im Vergleich zu '*' auswählen). Überprüfen Sie Ihre Daten und Ihr Schema regelmäßig, um sicherzustellen, dass Sie nie auf das "Garbage-In" -> "Garbage-Out" -Syndrom stoßen.

Vorausgesetzt, es gibt keine andere Lösung. Sie können Folgendes berücksichtigen. Es gibt immer mehrere Lösungen für ein Problem.

1) Indizierung: Mit select * wird ein Tabellenscan ausgeführt. Abhängig von verschiedenen Faktoren kann dies eine Festplattensuche und / oder einen Konflikt mit anderen Abfragen beinhalten. Wenn die Tabelle für mehrere Zwecke bestimmt ist, stellen Sie sicher, dass alle Abfragen performant sind, und führen Sie sie unterhalb Ihrer Zielzeiten aus. Wenn eine große Datenmenge vorhanden ist und Ihr Netzwerk oder eine andere Ressource nicht optimiert ist; Sie müssen dies berücksichtigen. Die Datenbank ist eine gemeinsam genutzte Umgebung.

2) Art der Lagerung. Dh wenn Sie SSDs, Festplatten oder Speicher verwenden. Die E / A-Zeiten und die Belastung des Systems / der CPU variieren.

3) Kann der DBA die Datenbank / Tabellen für eine höhere Leistung optimieren? Aus irgendeinem Grund haben die Teams entschieden, dass die Auswahl '*' die beste Lösung für das Problem ist. Kann die Datenbank oder Tabelle in den Speicher geladen werden? (Oder eine andere Methode ... Vielleicht wurde die Antwort so konzipiert, dass sie mit einer Verzögerung von 2-3 Sekunden reagiert? --- während eine Werbung abgespielt wird, um die Einnahmen des Unternehmens zu erzielen ...)

4) Beginnen Sie an der Basislinie. Verstehen Sie Ihre Datentypen und wie die Ergebnisse dargestellt werden. Bei kleineren Datentypen reduziert die Anzahl der Felder die in der Ergebnismenge zurückgegebene Datenmenge. Dadurch bleiben Ressourcen für andere Systemanforderungen verfügbar. Die Systemressourcen sind normalerweise begrenzt. Arbeiten Sie immer unter diesen Grenzen, um Stabilität und vorhersehbares Verhalten zu gewährleisten.

5) Größe der Tabelle / Daten. Wählen Sie '*' ist bei winzigen Tabellen üblich. Sie passen normalerweise in den Speicher und die Reaktionszeiten sind schnell. Nochmals .... überprüfen Sie Ihre Anforderungen. Plan für Feature Creep; Planen Sie immer den aktuellen und möglichen zukünftigen Bedarf.

6) Häufigkeit der Abfragen. Beachten Sie andere Workloads im System. Wenn diese Abfrage jede Sekunde ausgelöst wird und die Tabelle winzig ist. Die Ergebnismenge kann so gestaltet werden, dass sie im Cache / Speicher bleibt. Wenn es sich bei der Abfrage jedoch um einen häufigen Stapelprozess mit Gigabyte / Terabyte Daten handelt, sollten Sie möglicherweise zusätzliche Ressourcen bereitstellen, um sicherzustellen, dass andere Workloads nicht betroffen sind.

7) Zugehörige Workloads. Verstehen Sie, wie die Ressourcen verwendet werden. Ist das Netzwerk / System / Datenbank / Tabelle / Anwendung dediziert oder gemeinsam genutzt? Wer sind die Stakeholder? Ist dies für Produktion, Entwicklung oder Qualitätssicherung? Ist dies eine vorübergehende "schnelle Lösung". Haben Sie das Szenario getestet? Sie werden überrascht sein, wie viele Probleme heute auf der aktuellen Hardware auftreten können. (Ja, die Leistung ist schnell ... aber das Design / die Leistung ist immer noch beeinträchtigt.) Muss das System 10.000 Abfragen pro Sekunde gegenüber 5-10 Abfragen pro Sekunde ausführen? Ist der Datenbankserver dediziert oder führen andere Anwendungen die Überwachung für die gemeinsam genutzte Ressource aus? Einige Anwendungen / Sprachen; O / S verbrauchen 100% des Speichers und verursachen verschiedene Symptome / Probleme.

8) Test: Testen Sie Ihre Theorien und verstehen Sie so viel wie möglich. Ihr ausgewähltes '*' Problem kann eine große Sache sein, oder Sie müssen sich nicht einmal darum kümmern.

kllee
quelle