Warum man kein SELECT * FROM ... verwenden sollte

Hier findest du die Antworten auf häufig gestellte Fragen.
(kein Schreibrecht für Forenmitglieder!)
Antworten
akretschmer
Erfahrener Benutzer
Beiträge: 7458
Registriert: So 29. Okt 2006, 13:35
Wohnort: Kaufbach, Sachsen, Germany, Germany
Kontaktdaten:

Warum man kein SELECT * FROM ... verwenden sollte

Beitrag von akretschmer » So 28. Mär 2010, 12:57

Immer wieder liest man, ein simples SELECT * FROM ... sei böse und soll nicht verwendet werden. Doch warum ist das so?

1. Eine detaillierte Auflistung aller zu selektierenden Spalten ist faktisch gleichzeitig eine Dokumentation dessen, was der SELECT-Befehl zu liefern hat

2. wird damit expliziet die Reihenfolge der Spalten im Resultset definiert. Eine Änderung einer Tabelle via ALTER TABLE kann die physische Reihenfolge der Spalten ändern - und damit auch im Resultset von SELECT *

3. kann der Planner besser planen, was genau zu tun ist.

4. ganz wichtig: falls später die Tabelle um weitere Felder erweitert wird, im worst case um große TEXT oder BYTA-Felder mit großen Datenmengen (binäre Bilder z.B.), würde ein SELECT * unnötig große Datenmengen liefern, die der Client gar nicht braucht. Das SELECT * wurde ja eher geschrieben, das nun gelieferte Bild (als Beispiel) wird gar nicht gebraucht

5. Ist das Select ein JOIN über 2 oder mehr Tabellen, und eine oder mehrere dieser Tabellen werden später um neue Spalten ergänzt, kann es zu undefinierten Spaltenamen kommen:

Code: Alles auswählen

test=*# select a.id, a.name, c.* from account a left join client c on a.id=c.id where ts > '2010-01-01'::timestamp;
 id | name | id | name
----+------+----+------
(0 Zeilen)
 
Zeit: 0,369 ms
test=*# alter table client add column ts timestamp;
ALTER TABLE
Zeit: 0,526 ms
test=*# select a.id, a.name, c.* from account a left join client c on a.id=c.id where ts > '2010-01-01'::timestamp;
ERROR:  column reference "ts" is ambiguous
ZEILE 1: ...m account a left join client c on a.id=c.id where ts > '2010...
                                                              ^
test=!#


Also: in produktiven Code hat ein SELECT * nix zu suchen, und auch ein INSERT INTO ... VALUES () ohne Spaltendefinition ist falsch. In JOINS sind vollständige Spaltennamen zu verwenden!


Andreas
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

Antworten