Schemaänderungen
- Abrufen nach Reihenfolge --- Wenn der Code die Spalte # als Methode zum Abrufen der Daten abruft, werden die Spaltennummern durch eine Änderung des Schemas neu angepasst. Dies wird die Anwendung durcheinander bringen und es werden schlimme Dinge passieren.
- Abrufen nach Name --- Wenn der Code Spalten nach Namen abruft, z. B.
foo
, und eine andere Tabelle in der Abfrage eine Spalte hinzufügt foo
, kann die Art und Weise, wie dies behandelt wird, Probleme verursachen, wenn versucht wird, die richtige foo
Spalte abzurufen.
In beiden Fällen kann eine Schemaänderung Probleme beim Extrahieren der Daten verursachen.
Ferner prüfen , ob eine Spalte , die benutzt wurde, wird entfernt aus der Tabelle. Das select * from ...
klappt immer noch aber fehlerfrei beim Versuch die Daten aus der Ergebnismenge zu ziehen. Wenn die Spalte in der Abfrage angegeben ist, wird die Abfrage fehlschlagen und stattdessen eine eindeutige Angabe darüber geben, wo und was das Problem ist.
Datenaufwand
Mit einigen Spalten kann eine erhebliche Datenmenge verknüpft sein. Durch Auswahl von Zurück *
werden alle Daten abgerufen . Ja, hier ist der varchar(4096)
Wert für 1000 Zeilen, die Sie zurück ausgewählt haben. Dies gibt Ihnen zusätzliche mögliche 4 Megabyte an Daten, die Sie nicht benötigen, die aber trotzdem über die Leitung gesendet werden.
In Bezug auf die Schemaänderung ist das Varchar dort möglicherweise nicht vorhanden, als Sie die Tabelle zum ersten Mal erstellt haben, jetzt ist es dort.
Nichtvermittlung von Absichten
Wenn Sie "Zurück" auswählen *
und 20 Spalten erhalten, aber nur zwei davon benötigen, vermitteln Sie nicht die Absicht des Codes. Wenn man sich die Abfrage ansieht, weiß select *
man nicht, worauf es ankommt. Kann ich die Abfrage so ändern, dass stattdessen dieser andere Plan verwendet wird, um sie zu beschleunigen, indem diese Spalten nicht berücksichtigt werden? Ich weiß es nicht, weil die Absicht der Rückgabe der Abfrage nicht klar ist.
Schauen wir uns einige SQL-Fiddles an, die diese Schemaänderungen etwas genauer untersuchen.
Zunächst die ursprüngliche Datenbank: http://sqlfiddle.com/#!2/a67dd/1
DDL:
create table one (oneid int, data int, twoid int);
create table two (twoid int, other int);
insert into one values (1, 42, 2);
insert into two values (2, 43);
SQL:
select * from one join two on (one.twoid = two.twoid);
Und die Spalten, die Sie zurückerhalten oneid=1
, data=42
sind twoid=2
, und other=43
.
Was passiert nun, wenn ich einer Tabelle eine Spalte hinzufüge? http://sqlfiddle.com/#!2/cd0b0/1
alter table one add column other text;
update one set other = 'foo';
Und meine Ergebnisse aus der gleichen Abfrage nach wie vor sind oneid=1
, data=42
, twoid=2
, und other=foo
.
Eine Änderung in einer der Tabellen unterbricht die Werte von a select *
und plötzlich wird Ihre Bindung von 'other' an ein int einen Fehler auslösen, und Sie wissen nicht, warum.
Wenn stattdessen Ihre SQL-Anweisung war
select
one.oneid, one.data, two.twoid, two.other
from one join two on (one.twoid = two.twoid);
Die Änderung an Tabelle eins hätte Ihre Daten nicht gestört. Diese Abfrage wird vor und nach der Änderung gleich ausgeführt.
Indizierung
Wenn Sie eine select * from
ausführen, ziehen Sie alle Zeilen aus allen Tabellen, die den Bedingungen entsprechen. Sogar Tische, die dir wirklich egal sind. Während dies bedeutet, dass mehr Daten übertragen werden, lauert ein weiteres Leistungsproblem weiter unten im Stapel.
Indizes. (bezogen auf SO: Wie verwende ich den Index in der select-Anweisung? )
Wenn Sie viele Spalten zurückziehen, ignoriert das Datenbankplanoptimierungsprogramm möglicherweise die Verwendung eines Index, da Sie trotzdem alle diese Spalten abrufen müssen und es mehr Zeit in Anspruch nehmen würde, den Index und dann alle Spalten in der Abfrage abzurufen als wäre es nur ein kompletter Tabellenscan zu machen.
Wenn Sie nur den Nachnamen eines Benutzers auswählen (den Sie häufig verwenden und auf dem Sie einen Index haben), kann die Datenbank nur einen Index-Scan durchführen (nur Index-Scan für Postgres-Wiki , vollständiger MySQL- Tabellenscan vs vollständiger Index-Scan , Nur-Index-Scan: Vermeiden des Tabellenzugriffs ).
Es gibt eine ganze Reihe von Optimierungen, wenn möglich, nur aus Indizes zu lesen. Die Informationen können auf jeder Indexseite schneller abgerufen werden, da Sie auch weniger davon abrufen - Sie ziehen nicht alle anderen Spalten für die Indexseite ab select *
. Es ist möglich, dass ein Nur-Index-Scan Ergebnisse in der Größenordnung von 100x schneller zurückgibt (Quelle: Wählen Sie * ist schlecht ).
Dies bedeutet nicht, dass ein vollständiger Index-Scan großartig ist, er ist immer noch ein vollständiger Scan - aber er ist besser als ein vollständiger Tabellenscan. Sobald Sie alle Möglichkeiten select *
ausloten, die der Leistung schaden, finden Sie immer wieder neue.
Verwandte Lesung