select * vs select column


124

Wenn ich nur 2/3 Spalten brauche und abfrage SELECT * anstatt diese Spalten in einer ausgewählten Abfrage bereitzustellen, gibt es Leistungseinbußen in Bezug auf mehr / weniger E / A oder Speicher?

Der Netzwerk-Overhead kann vorhanden sein, wenn ich * ohne Notwendigkeit auswähle.

Zieht das Datenbankmodul bei einer Auswahloperation immer ein Atomtupel von der Festplatte oder nur die Spalten, die bei der Auswahloperation angefordert wurden?

Wenn immer ein Tupel gezogen wird, ist der E / A-Overhead derselbe.

Gleichzeitig kann es zu einem Speicherverbrauch kommen, um die angeforderten Spalten aus dem Tupel zu entfernen, wenn ein Tupel gezogen wird.

Wenn dies der Fall ist, hat select someColumn mehr Speicheraufwand als select *


Gibt es ein bestimmtes RDBMS, nach dem Sie fragen? Es ist möglich, dass SELECTdie Ausführung / Verarbeitung von Abfragen von Datenbank zu Datenbank unterschiedlich ist.
Lèse Majesté

10
Abgesehen davon, wenn Sie in PostgreSQL sagen, dass Sie CREATE VIEW foo_view AS SELECT * FROM foo;später Spalten zur Tabelle foo hinzufügen, werden diese Spalten nicht automatisch wie erwartet in foo_view angezeigt. Mit anderen Worten, das wird *in diesem Kontext nur einmal (zum Zeitpunkt der Ansichtserstellung) erweitert, nicht per SELECT. Aufgrund von Komplikationen, die sich aus ALTER TABLE ergeben, würde ich sagen, dass (in der Praxis) *als schädlich angesehen wird.
Joey Adams

@JoeyAdams - nicht nur PostgresQL, dies ist auch das Verhalten von Oracle.
APC

1
@OMG Ponys: Mir war kein ähnlicher Beitrag bekannt. Diese sind jedoch nicht wirklich similer. @ Lèse majesté: Ich spreche von generischem RDBMS. nicht über einen bestimmten Anbieter @Joey Adams: Hmm, ich weiß, dass * unsicher ist. Ich möchte nur die Leistungsprobleme in Bezug auf diskutieren.
Neel Basu

Antworten:


31

Es wird immer ein Tupel gezogen (außer in Fällen, in denen die Tabelle vertikal segmentiert wurde - in Spalten aufgeteilt). Um die von Ihnen gestellte Frage zu beantworten, spielt dies aus Sicht der Leistung keine Rolle. Aus vielen anderen Gründen (unten) sollten Sie jedoch immer speziell die gewünschten Spalten nach Namen auswählen.

Es wird immer ein Tupel gezogen, da (in jedem mir bekannten RDBMS eines Anbieters) die zugrunde liegende Speicherstruktur auf der Festplatte für alles (einschließlich Tabellendaten) auf definierten E / A-Seiten basiert (in SQL Server beispielsweise für jede Seite) 8 Kilobyte). Und jedes Lesen oder Schreiben von E / A erfolgt nach Seiten. Das heißt, jedes Schreiben oder Lesen ist eine vollständige Seite mit Daten.

Aufgrund dieser zugrunde liegenden strukturellen Einschränkung muss sich jede Datenzeile in einer Datenbank immer auf einer und nur einer Seite befinden. Es kann nicht mehrere Datenseiten umfassen (mit Ausnahme spezieller Dinge wie Blobs, bei denen die tatsächlichen Blob-Daten in separaten Seitenblöcken gespeichert werden und die tatsächliche Tabellenzeilenspalte dann nur einen Zeiger erhält ...). Diese Ausnahmen sind jedoch nur Ausnahmen und gelten im Allgemeinen nur in besonderen Fällen (für besondere Datentypen oder bestimmte Optimierungen für besondere Umstände).
Selbst in diesen besonderen Fällen gilt im Allgemeinen die tatsächliche Tabellenzeilenzeile selbst (die enthält) Der Zeiger auf die tatsächlichen Daten für den Blob oder was auch immer) muss auf einer einzelnen E / A-Seite gespeichert werden ...

AUSNAHME. Der einzige Ort, an dem Select *OK ist, befindet sich in der Unterabfrage nach einer Existsoder Not ExistsPrädikatklausel, wie in:

   Select colA, colB
   From table1 t1
   Where Exists (Select * From Table2
                 Where column = t1.colA)

BEARBEITEN: Um den Kommentar von @Mike Sherer anzusprechen: Ja, es ist wahr, sowohl technisch, mit ein wenig Definition für Ihren speziellen Fall, als auch ästhetisch. Erstens muss der Abfrageprozessor aus den gleichen Gründen jede Spalte abrufen, die in einem Index gespeichert ist, und nicht nur die angeforderten, aus denselben Gründen - ALLE E / A müssen in ausgeführt werden Seiten und Indexdaten werden wie Tabellendaten in E / A-Seiten gespeichert. Wenn Sie also "Tupel" für eine Indexseite als die im Index gespeicherten Spalten definieren, ist die Anweisung weiterhin wahr.
und die Aussage ist ästhetisch wahr, weil der Punkt ist, dass sie Daten basierend auf dem abruft, was auf der E / A-Seite gespeichert ist, nicht auf dem, was Sie verlangen, und dies wahr, ob Sie auf die E / A-Seite der Basistabelle oder einen Index zugreifen E / A-Seite.

Weitere Gründe für die Nichtverwendung Select *finden Sie unter Warum wird dies SELECT *als schädlich angesehen? ::


"Es zieht immer ein Tupel" sind Sie sicher? Hmm Okay Also ich hatte recht. In diesem Fall select *ist der Speicheraufwand geringer als der select columngleiche E / A-Aufwand. Also, wenn wir den Netzwerk-Overhead verlassen. select *wenn weniger Overhead als der vonselect column
Neel Basu

10
Das ist nicht wahr. Ein Beispiel aus dem Kopf ist, wenn Sie nur den Wert einer indizierten Spalte in MySQL möchten (zum Beispiel nur, um die Zeilenexistenz zu überprüfen) und die MyISAM-Speicher-Engine verwenden, werden die Daten aus dem abgerufen MYI-Datei, die sich im Speicher befinden könnte und nicht einmal auf die Festplatte geht!
Mike Sherov

Ja, wenn sich der angeforderte Tupelsatz im Speicher befindet, gibt es keine E / A, aber das ist ein Sonderfall. Also, was ist der Sommer. Wenn ich eine indizierte Spalte auswähle, wird dann nicht das gesamte Tupel gelesen? sonst wird das ganze Tupel gelesen?
Neel Basu

Ich bin mir nicht ganz sicher, wie MySql das Caching durchführt, aber in SQL Server und Oracle wird auch dann, wenn sich Daten im Arbeitsspeicher befinden, mit derselben Seitenstruktur darauf zugegriffen wie beim Zugriff von der Festplatte. Dies bedeutet, dass eine Speicher-E / A pro Datenseite erforderlich wäre ... genau wie auf der Festplatte. (außer Speicher-E / A sind natürlich viel schneller als Festplatten-E / A.). In der Tat ist dies ein Ziel des Caching-Designs, um den Zugriffsprozess völlig unabhängig vom Standort der Daten zu machen.
Charles Bretana

2
Können Sie das "aus vielen anderen Gründen" genauer formulieren? Weil mir das nicht klar war. Wenn die Leistung keine Rolle spielt, warum sollten Sie dann Spaltennamen anfordern?
Dennis

111

Es gibt mehrere Gründe, die Sie niemals (niemals) SELECT *im Produktionscode verwenden sollten:

  • Da Sie Ihrer Datenbank keine Hinweise geben, was Sie möchten, muss sie zuerst die Definition der Tabelle überprüfen, um die Spalten in dieser Tabelle zu bestimmen. Diese Suche kostet einige Zeit - nicht viel in einer einzelnen Abfrage - aber sie summiert sich im Laufe der Zeit

  • Wenn Sie nur 2/3 der Spalten benötigen, wählen Sie 1/3 zu viele Daten aus, die von der Festplatte abgerufen und über das Netzwerk gesendet werden müssen

  • Wenn Sie sich auf bestimmte Aspekte der Daten verlassen, z. B. die Reihenfolge der zurückgegebenen Spalten, kann es zu einer bösen Überraschung kommen, wenn die Tabelle neu organisiert und neue Spalten hinzugefügt (oder vorhandene entfernt) werden.

  • Wenn Sie in SQL Server (bei anderen Datenbanken nicht sicher) eine Teilmenge von Spalten benötigen, besteht immer die Möglichkeit, dass ein nicht gruppierter Index diese Anforderung abdeckt (enthält alle erforderlichen Spalten). Mit a geben SELECT *Sie diese Möglichkeit von Anfang an auf. In diesem speziellen Fall würden die Daten von den Indexseiten abgerufen (wenn diese alle erforderlichen Spalten enthalten), und somit wären die Festplatten-E / A und der Speicheraufwand im Vergleich zur Durchführung einer SELECT *....Abfrage viel geringer .

Ja, die Eingabe erfordert anfangs etwas mehr Zeit (Tools wie SQL Prompt for SQL Server helfen Ihnen sogar dabei) - aber dies ist wirklich ein Fall, in dem es ausnahmslos eine Regel gibt: Verwenden Sie niemals SELECT * in Ihrem Produktionscode. JE.


13
Obwohl Sie in der Praxis mit Ihnen einverstanden sind, sind Sie sicherlich in allen Fällen richtig, wenn Sie Spaltendaten aus der Tabelle abrufen (wie in dieser Frage angesprochen). Ihre Betonung auf EVER veranlasst mich jedoch, darauf hinzuweisen, dass diese Regeln nicht für ALLE SQL-Abfragen allgemein sind. Insbesondere wird es in einer Unterabfrage nach einem EXISTS-Prädikat verwendet (wie in Where Exists (Select * From ...). Die Verwendung von Select *ist sicherlich kein Problem und wird in einigen Kreisen als bewährte Methode angesehen.
Charles Bretana

3
@ Charles Bretana: Ja, das IF EXISTS(SELECT *...ist ein Sonderfall - da dort keine Daten wirklich abgerufen werden, aber es nur eine Überprüfung auf Existenz ist, ist das SELECT * dort kein Problem ...
marc_s

1
Was ist, wenn ich eine API entwickle, mit der Daten aus einer meiner Tabellen abgerufen werden können? Da ich nicht wissen würde, an welchen Daten der Benutzer interessiert ist, wäre SELECT * wahrscheinlich akzeptabel.
Simon Bengtsson

1
@SimonBengtsson: Ich würde immer noch dagegen argumentieren - Angenommen, Sie haben einige "administrative" Daten in bestimmten Spalten in Ihrer Tabelle, die Sie dem Kunden nicht zugänglich machen möchten? Ich würde immer explizit eine Liste von Spalten angeben, die
abgerufen werden sollen

1
Das ist richtig. Was ist, wenn Sie eine Ansicht abfragen, die speziell für die Verwendung mit der API eingerichtet wurde?
Simon Bengtsson

21

Sie sollten immer nur selectdie Spalten verwenden, die Sie tatsächlich benötigen. Es ist nie weniger effizient, weniger statt mehr auszuwählen, und Sie haben auch weniger unerwartete Nebenwirkungen - wie den Zugriff auf Ihre Ergebnisspalten auf der Clientseite über den Index, und dann werden diese Indizes durch Hinzufügen einer neuen Spalte zur Tabelle falsch.

[Bearbeiten]: Bedeutet Zugriff. Dummes Gehirn wacht immer noch auf.


3
+1 für einen Randfall, an den meines Erachtens nicht viele auf den ersten Blick denken werden - Indizes auf der Clientseite und hinzugefügte / geänderte Spalten.
Tomas Aschan

1
Ja, aber ist die Verwendung von numerischen Indizes für Spalten so häufig? Ich habe immer auf Spaltendaten mit Zeichenfolgenschlüsseln oder Eigenschaftsnamen zugegriffen, wenn ORM verwendet wurde.
Lèse Majesté

11
Als ich dies vor langer Zeit sah, wählte der Junior-Programmierer * aus einer Tabelle aus und machte Annahmen über die Spaltenreihenfolge. Sein ganzer Code brach, sobald jemand anderes die Tabelle wechselte. Was für ein Spaß wir hatten.
Paul McKenzie

7
Es ist wahrscheinlich eine schlechte Idee, die Spaltenreihenfolge im Allgemeinen nur aus Gründen der Lesbarkeit des Codes zu verwenden, doppelt schlecht, um SELECT *sie damit zu verwenden.
Lèse Majesté

2
Wow, der Zugriff auf Spalten über den Index im Client-Code scheint eine phänomenal schlechte Idee zu sein. Was das betrifft, in der Größenordnung unter Berufung in der die Spalten in einer Ergebnismenge erscheinen in irgendeiner Weise fühlt sich sehr schmutzig zu mir.
Matt Peterson

7

Wenn Sie keine großen Blobs speichern, spielt die Leistung keine Rolle. Der Hauptgrund, SELECT * nicht zu verwenden, besteht darin, dass bei Verwendung von zurückgegebenen Zeilen als Tupel die Spalten in der vom Schema angegebenen Reihenfolge zurückgegeben werden. Wenn sich dies ändert, müssen Sie den gesamten Code korrigieren.

Wenn Sie dagegen den Zugriff im Wörterbuchstil verwenden, spielt es keine Rolle, in welcher Reihenfolge die Spalten wieder angezeigt werden, da Sie immer über den Namen auf sie zugreifen.


6

Dies lässt mich sofort an eine Tabelle denken, die ich verwendet habe und die eine Spalte vom Typ enthielt blob. Es enthielt normalerweise ein JPEG-Bild mit einer MbGröße von einigen Sekunden.

Unnötig zu erwähnen, dass ich diese SELECTKolumne nicht verwendet habe , es sei denn, ich brauchte sie wirklich . Es war nur ein Ärger, diese Daten im Umlauf zu haben - besonders wenn ich mehrere Zeilen ausgewählt habe.

Ich gebe jedoch zu, dass ich sonst normalerweise alle Spalten in einer Tabelle abfrage.


20
LOB-Spalten sind immer mein Lieblingsbeispiel für die Gefahren von SELECT *. Also wollte ich Sie positiv bewerten, bis ich den dritten Absatz gelesen habe. TSK tsk. Was passiert, wenn ein anderer Entwickler einer Tabelle, die derzeit keine solche Spalte enthält, ein BLOB hinzufügt?
APC

1
@APC, ich wünschte, ich könnte Ihren Kommentar mehr positiv bewerten. Denken Sie an Ihren armen Kollegen, der nur eine Spalte hinzufügen möchte, ohne einen großen Leistungsabfall zu verursachen! Denken Sie daran, wie wütend sie sein werden, wenn sie nach ein paar Stunden Ihre unschuldig aussehende Auswahl * entdecken.
Mike Sherov

1
@ user256007, ja, auch ohne BLOB ... BLOB veranschaulicht nur das extreme Beispiel. Überprüfen Sie meine Antwort an Charles. Es gibt Zeiten, in denen Sie durch Auswahl bestimmter Spalten die Daten aus dem Speicher abrufen können, ohne auf die Festplatte zu gehen.
Mike Sherov

1
@Richard, ich denke, sie eignen sich hervorragend, wenn die Optimierung der DB-Leistung nicht Ihr Hauptanliegen ist, was in 99% der Fälle der Fall ist. Wie bei den meisten Frameworks tendieren sie dazu, Dinge zu verallgemeinern, um eine schnellere Entwicklung zu ermöglichen und gleichzeitig die reine Leistung zu beeinträchtigen. Wie Knuth sagte: "Vorzeitige Optimierung ist die Wurzel allen Übels." Wenn Sie an einem Punkt angelangt sind, an dem Sie sich Gedanken über die Leistung ausgewählter Spalten im Vergleich zu select * machen müssen (fragen Sie Twitter nach RoR), können Sie sich darüber Gedanken machen und es dann optimieren. Wenn das Framework nicht robust genug ist, um dies zu unterstützen, würde ich sagen, dass Sie das falsche Framework verwenden.
Mike Sherov

1
@ user256007 - Die allgemeine Regel lautet "Verwenden Sie nicht SELECT *". Die Antwort von marc_s hat alle Gründe, warum dies der Fall ist.
APC

6

Während einer SQL-Auswahl verweist die Datenbank immer auf die Metadaten für die Tabelle, unabhängig davon, ob es sich um SELECT * für SELECT a, b, c handelt ... Warum? Denn dort befinden sich die Informationen zur Struktur und zum Layout der Tabelle im System.

Diese Informationen müssen aus zwei Gründen gelesen werden. Erstens, um die Aussage einfach zusammenzustellen. Es muss sichergestellt sein, dass Sie mindestens eine vorhandene Tabelle angeben. Außerdem hat sich möglicherweise die Datenbankstruktur seit der letzten Ausführung einer Anweisung geändert.

Natürlich werden DB-Metadaten im System zwischengespeichert, aber es muss noch verarbeitet werden.

Als Nächstes werden die Metadaten zum Generieren des Abfrageplans verwendet. Dies geschieht jedes Mal, wenn eine Anweisung ebenfalls kompiliert wird. Dies läuft wiederum gegen zwischengespeicherte Metadaten, wird aber immer ausgeführt.

Diese Verarbeitung wird nur dann nicht durchgeführt, wenn die Datenbank eine vorkompilierte Abfrage verwendet oder eine vorherige Abfrage zwischengespeichert hat. Dies ist das Argument für die Verwendung von Bindungsparametern anstelle von wörtlichem SQL. "SELECT * FROM TABLE WHERE key = 1" ist eine andere Abfrage als "SELECT * FROM TABLE WHERE key =?" und die "1" ist an den Anruf gebunden.

DBs sind für ihre Arbeit stark auf das Zwischenspeichern von Seiten angewiesen. Viele moderne DBs sind klein genug, um vollständig in den Speicher zu passen (oder, vielleicht sollte ich sagen, der moderne Speicher ist groß genug, um in viele DBs zu passen). Dann sind Ihre primären E / A-Kosten im Back-End Protokollierung und Seitenlöschung.

Wenn Sie jedoch immer noch auf die Festplatte für Ihre Datenbank zugreifen, besteht eine Hauptoptimierung vieler Systeme darin, sich auf die Daten in Indizes und nicht auf die Tabellen selbst zu verlassen.

Wenn Sie haben:

CREATE TABLE customer (
    id INTEGER NOT NULL PRIMARY KEY,
    name VARCHAR(150) NOT NULL,
    city VARCHAR(30),
    state VARCHAR(30),
    zip VARCHAR(10));

CREATE INDEX k1_customer ON customer(id, name);

Wenn Sie dann "ID AUSWÄHLEN, Name VON Kunde WHERE ID = 1" ausführen, ist es sehr wahrscheinlich, dass Ihre Datenbank diese Daten aus dem Index und nicht aus den Tabellen abruft.

Warum? Der Index wird wahrscheinlich trotzdem verwendet, um die Abfrage zu erfüllen (im Vergleich zu einem Tabellenscan), und obwohl 'name' in der where-Klausel nicht verwendet wird, ist dieser Index immer noch die beste Option für die Abfrage.

Jetzt verfügt die Datenbank über alle Daten, die zur Erfüllung der Abfrage erforderlich sind. Es gibt also keinen Grund, die Tabellenseiten selbst aufzurufen. Die Verwendung des Index führt zu weniger Festplattenverkehr, da der Index eine höhere Zeilendichte aufweist als die Tabelle im Allgemeinen.

Dies ist eine handwellige Erklärung einer bestimmten Optimierungstechnik, die von einigen Datenbanken verwendet wird. Viele haben verschiedene Optimierungs- und Optimierungstechniken.

Am Ende ist SELECT * nützlich für dynamische Abfragen, die Sie manuell eingeben müssen. Ich würde es niemals für "echten Code" verwenden. Durch die Identifizierung einzelner Spalten erhält die Datenbank mehr Informationen, mit denen sie die Abfrage optimieren kann, und Sie können Ihren Code besser gegen Schemaänderungen usw. steuern.


Will, ich habe Ihre Antwort abgelehnt, nur weil Sie NOT NULL zusammen mit dem PRIMARY KEY verwenden. Gibt es einen guten Grund für Sie, so zu schreiben?
Lerner

4

Ich denke, es gibt keine genaue Antwort auf Ihre Frage, da Sie über die Leistung und die Möglichkeit nachdenken, Ihre Apps zu warten. Select columnist performativer select *, aber wenn Sie ein orientiertes Objektsystem entwickeln, dann werden Sie die Verwendung mögen object.propertiesund Sie können Eigenschaften in jedem Teil von Apps benötigen, dann müssen Sie mehr Methoden schreiben, um Eigenschaften in speziellen Situationen zu erhalten, wenn Sie dies nicht tun Verwenden select *und füllen Sie alle Eigenschaften. Ihre Apps müssen eine gute Leistung aufweisen, select *und in einigen Fällen müssen Sie eine Auswahlspalte verwenden, um die Leistung zu verbessern. Dann haben Sie die bessere von zwei Welten, die Möglichkeit, Apps und Leistung zu schreiben und zu warten, wenn Sie Leistung benötigen.


4

Die hier akzeptierte Antwort ist falsch. Ich bin darauf gestoßen, als eine andere Frage als Duplikat davon geschlossen wurde (während ich noch meine Antwort schrieb - grr - daher verweist die folgende SQL auf die andere Frage).

Sie sollten immer das SELECT-Attribut, das Attribut .... NOT SELECT * verwenden

Es ist in erster Linie für Leistungsprobleme.

SELECT name FROM users WHERE name = 'John';

Ist kein sehr nützliches Beispiel. Betrachten Sie stattdessen:

SELECT telephone FROM users WHERE name='John';

Wenn ein Index aktiviert ist (Name, Telefon), kann die Abfrage gelöst werden, ohne dass die relevanten Werte aus der Tabelle nachgeschlagen werden müssen - es gibt einen abdeckenden Index.

Angenommen, die Tabelle enthält ein BLOB mit einem Bild des Benutzers und einem hochgeladenen Lebenslauf sowie eine Tabelle. Wenn Sie SELECT * verwenden, werden alle diese Informationen in die DBMS-Puffer zurückgeführt (wodurch andere nützliche Informationen aus dem Cache entfernt werden). Dann wird alles an den Client gesendet, wobei die Betriebszeit im Netzwerk und der Speicher auf dem Client für redundante Daten verwendet werden.

Dies kann auch zu Funktionsproblemen führen, wenn der Client die Daten als aufgezähltes Array abruft (z. B. mysql_fetch_array ($ x, MYSQL_NUM) von PHP). Vielleicht war 'Telefon', als der Code geschrieben wurde, die dritte Spalte, die von SELECT * zurückgegeben wurde, aber dann kommt jemand und beschließt, der Tabelle eine E-Mail-Adresse hinzuzufügen, die vor 'Telefon' steht. Das gewünschte Feld wird nun in die 4. Spalte verschoben.


2

Es gibt Gründe, Dinge so oder so zu tun. Ich verwende SELECT * häufig in PostgreSQL, da Sie mit SELECT * in PostgreSQL viele Dinge tun können, die Sie mit einer expliziten Spaltenliste nicht tun können, insbesondere in gespeicherten Prozeduren. In ähnlicher Weise kann SELECT * über einem geerbten Tabellenbaum in Informix zu gezackten Zeilen führen, während eine explizite Spaltenliste dies nicht kann, da zusätzliche Spalten in untergeordneten Tabellen ebenfalls zurückgegeben werden.

Der Hauptgrund, warum ich dies in PostgreSQL mache, ist, dass es sicherstellt, dass ich einen wohlgeformten Typ bekomme, der für eine Tabelle spezifisch ist. Dadurch kann ich die Ergebnisse als Tabellentyp in PostgreSQL verwenden. Dies ermöglicht auch viel mehr Optionen in der Abfrage als eine starre Spaltenliste.

Auf der anderen Seite können Sie anhand einer starren Spaltenliste überprüfen, ob sich die Datenbankschemata auf bestimmte Weise nicht geändert haben. Dies kann hilfreich sein. (Ich mache solche Überprüfungen auf einer anderen Ebene.)

In Bezug auf die Leistung verwende ich normalerweise VIEWs und gespeicherte Prozeduren, die Typen zurückgeben (und dann eine Spaltenliste innerhalb der gespeicherten Prozedur). Dies gibt mir die Kontrolle darüber, welche Typen zurückgegeben werden.

Aber denken Sie daran, dass ich SELECT * normalerweise für eine Abstraktionsschicht anstelle von Basistabellen verwende.


2

Referenz aus diesem Artikel:

Ohne SELECT *: Wenn Sie zu diesem Zeitpunkt "SELECT *" verwenden, wählen Sie weitere Spalten aus der Datenbank aus, und einige dieser Spalten werden möglicherweise nicht von Ihrer Anwendung verwendet. Dies führt zu zusätzlichen Kosten und einer Belastung des Datenbanksystems und zu mehr Datenübertragungen über das Netzwerk.

Mit SELECT *: Wenn Sie spezielle Anforderungen haben und beim Hinzufügen oder Löschen eine Spalte erstellt haben, die automatisch nach Anwendungscode behandelt wird. 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.


0

Nur um der Diskussion eine Nuance hinzuzufügen, die ich hier nicht sehe: In Bezug auf E / A, wenn Sie eine Datenbank mit spaltenorientiertem Speicher verwenden verwenden, VIEL weniger E / A ausführen, wenn Sie nur bestimmte Fragen stellen Säulen. Wenn wir zu SSDs wechseln, sind die Vorteile im Vergleich zum zeilenorientierten Speicher möglicherweise etwas geringer, aber es gibt a) nur das Lesen der Blöcke, die Spalten enthalten, die Ihnen wichtig sind, b) die Komprimierung, wodurch die Größe der Daten auf der Festplatte und damit die Daten im Allgemeinen erheblich reduziert werden Datenvolumen von der Festplatte gelesen.

Wenn Sie mit spaltenorientiertem Speicher nicht vertraut sind, stammt eine Implementierung für Postgres von Citus Data, eine andere für Greenplum, eine andere für Paraccel und eine andere (lose gesagt) für Amazon Redshift. Für MySQL gibt es Infobright, die mittlerweile fast nicht mehr existierende InfiniDB. Weitere kommerzielle Angebote sind Vertica von HP, Sybase IQ, Teradata ...


-1
select * from table1 INTERSECT  select * from table2

gleich

select distinct t1 from table1 where Exists (select t2 from table2 where table1.t1 = t2 )

Könnten Sie bitte Ihren Code formatieren, indem Sie ihn markieren und Strg + K
WhatsThePoint
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.