Die Spaltenreihenfolge hatte große Auswirkungen auf die Leistung einiger der von mir optimierten Datenbanken, die sich über SQL Server, Oracle und MySQL erstrecken. Dieser Beitrag hat gute Faustregeln :
- Primärschlüsselspalten zuerst
- Fremdschlüsselspalten weiter.
- Häufig durchsuchte Spalten weiter
- Häufig aktualisierte Spalten später
- Nullable Spalten zuletzt.
- Am wenigsten verwendete nullfähige Spalten nach häufiger verwendeten nullbaren Spalten
Ein Beispiel für Leistungsunterschiede ist eine Indexsuche. Das Datenbankmodul findet eine Zeile basierend auf einigen Bedingungen im Index und erhält eine Zeilenadresse zurück. Angenommen, Sie suchen nach SomeValue und es befindet sich in dieser Tabelle:
SomeId int,
SomeString varchar(100),
SomeValue int
Die Engine muss raten, wo SomeValue startet, da SomeString eine unbekannte Länge hat. Wenn Sie jedoch die Reihenfolge ändern in:
SomeId int,
SomeValue int,
SomeString varchar(100)
Jetzt weiß die Engine, dass SomeValue 4 Bytes nach dem Start der Zeile gefunden werden kann. Die Spaltenreihenfolge kann daher erhebliche Auswirkungen auf die Leistung haben.
BEARBEITEN: SQL Server 2005 speichert Felder mit fester Länge am Anfang der Zeile. Und jede Zeile hat einen Verweis auf den Beginn eines Varchars. Dies negiert den oben aufgeführten Effekt vollständig. Bei neueren Datenbanken hat die Spaltenreihenfolge keine Auswirkungen mehr.
Aktualisieren:
In
MySQL
kann es einen Grund dafür geben.Da variable Datentypen (wie
VARCHAR
) mit variablen Längen inInnoDB
gespeichert werden, sollte das Datenbankmodul alle vorherigen Spalten in jeder Zeile durchlaufen, um den Versatz der angegebenen zu ermitteln.Die Auswirkung kann bei Spalten bis zu 17%
20
betragen.Siehe diesen Eintrag in meinem Blog für weitere Details:
In
Oracle
nachgestelltenNULL
Spalten wird kein Speicherplatz belegt. Deshalb sollten Sie sie immer an das Ende der Tabelle setzen.Auch in
Oracle
und inSQL Server
, im Falle einer großen Reihe,ROW CHAINING
kann a auftreten.ROW CHANING
teilt eine Zeile, die nicht in einen Block passt, und verteilt sie auf mehrere Blöcke, die mit einer verknüpften Liste verbunden sind.Das Lesen von nachfolgenden Spalten, die nicht in den ersten Block passen, erfordert das Durchlaufen der verknüpften Liste, was zu einer zusätzlichen
I/O
Operation führt.Siehe diese Seite zur Veranschaulichung
ROW CHAINING
inOracle
:Aus diesem Grund sollten Sie häufig verwendete Spalten an den Anfang der Tabelle und Spalten, die Sie nicht häufig verwenden, oder Spalten, die häufig verwendet werden
NULL
, an das Ende der Tabelle setzen.Wichtige Notiz:
Wenn Ihnen diese Antwort gefällt und Sie dafür stimmen möchten, stimmen Sie bitte auch für
@Andomar
die Antwort ab .Er antwortete auf das Gleiche, scheint aber ohne Grund abgelehnt zu werden.
quelle
Während der Oracle-Schulung bei einem früheren Job schlug unser DBA vor, dass es vorteilhaft sei, alle nicht nullbaren Spalten vor die nullbaren zu setzen ... obwohl TBH ich mich nicht an die Details des Grundes erinnere. Oder waren es vielleicht nur diejenigen, die wahrscheinlich aktualisiert wurden, die am Ende gehen sollten? (Vielleicht muss die Zeile verschoben werden, wenn sie erweitert wird.)
Im Allgemeinen sollte es keinen Unterschied machen. Wie Sie sagen, sollten Abfragen immer Spalten selbst angeben, anstatt sich auf die Reihenfolge von "select *" zu verlassen. Ich kenne keine Datenbank, mit der sie geändert werden können ... nun, ich wusste nicht, dass MySQL dies zulässt, bis Sie es erwähnt haben.
quelle
Einige schlecht geschriebene Anwendungen hängen möglicherweise von der Spaltenreihenfolge / dem Spaltenindex anstelle des Spaltennamens ab. Sie sollten es nicht sein, aber es passiert. Das Ändern der Reihenfolge der Spalten würde solche Anwendungen beschädigen.
quelle
Nein, die Reihenfolge der Spalten in einer SQL-Datenbanktabelle ist völlig irrelevant - außer für Anzeige- / Druckzwecke. Es macht keinen Sinn, Spalten neu anzuordnen - die meisten Systeme bieten nicht einmal eine Möglichkeit, dies zu tun (außer die alte Tabelle zu löschen und sie mit der neuen Spaltenreihenfolge neu zu erstellen).
Marc
BEARBEITEN: Aus dem Wikipedia-Eintrag in der relationalen Datenbank ist hier der relevante Teil, der mir klar zeigt, dass die Spaltenreihenfolge niemals von Belang sein sollte:
Eine Beziehung ist definiert als eine Menge von n-Tupeln. Sowohl in der Mathematik als auch im relationalen Datenbankmodell ist eine Menge eine ungeordnete Sammlung von Elementen, obwohl einige DBMS ihren Daten eine Reihenfolge auferlegen. In der Mathematik hat ein Tupel eine Reihenfolge und ermöglicht die Vervielfältigung. EF Codd definierte ursprünglich Tupel unter Verwendung dieser mathematischen Definition. Später war es eine der großartigen Erkenntnisse von EF Codd, dass die Verwendung von Attributnamen anstelle einer Reihenfolge in einer auf Beziehungen basierenden Computersprache (im Allgemeinen) viel praktischer wäre. Diese Erkenntnis wird noch heute genutzt.
quelle
Lesbarkeit der Ausgabe, wenn Sie Folgendes eingeben müssen:
in Ihrer Datenbankverwaltungssoftware?
Es ist ein sehr falscher Grund, aber im Moment fällt mir nichts anderes ein.
quelle
Der einzige Grund, an den ich denken kann, ist das Debuggen und die Brandbekämpfung. Wir haben eine Tabelle, deren "Name" -Spalte ungefähr auf Platz 10 der Liste steht. Es ist schmerzhaft, wenn Sie eine schnelle Auswahl * aus der Tabelle mit der ID in (1,2,3) vornehmen und dann einen Bildlauf durchführen müssen, um die Namen anzuzeigen.
Aber das war es schon.
quelle
Wie so oft ist der größte Faktor der nächste, der am System arbeiten muss. Ich versuche, zuerst die Primärschlüsselspalten, dann die Fremdschlüsselspalten und dann den Rest der Spalten in absteigender Reihenfolge der Wichtigkeit / Bedeutung für das System zu haben.
quelle
Wenn Sie UNION häufig verwenden, erleichtert dies das Abgleichen von Spalten, wenn Sie eine Konvention über deren Reihenfolge haben.
quelle
Wie bereits erwähnt, gibt es zahlreiche potenzielle Leistungsprobleme. Ich habe einmal an einer Datenbank gearbeitet, in der das Platzieren sehr großer Spalten am Ende die Leistung verbesserte, wenn Sie diese Spalten in Ihrer Abfrage nicht referenzierten. Wenn ein Datensatz mehrere Plattenblöcke umfasst, kann das Datenbankmodul anscheinend das Lesen von Blöcken beenden, sobald alle erforderlichen Spalten vorhanden sind.
Natürlich hängen die Auswirkungen auf die Leistung nicht nur stark vom Hersteller ab, den Sie verwenden, sondern möglicherweise auch von der Version. Vor einigen Monaten habe ich festgestellt, dass unsere Postgres keinen Index für einen "Gefällt mir" -Vergleich verwenden konnten. Das heißt, wenn Sie "eine Spalte wie 'M%'" geschrieben haben, war es nicht klug genug, zu den Ms zu springen und zu beenden, wenn das erste N gefunden wurde. Ich hatte vor, eine Reihe von Abfragen zu ändern, um "zwischen" zu verwenden. Dann haben wir eine neue Version von Postgres bekommen, die intelligent mit ähnlichen Dingen umgeht. Ich bin froh, dass ich nie dazu gekommen bin, die Abfragen zu ändern. Natürlich nicht direkt relevant, aber mein Punkt ist, dass alles, was Sie aus Effizienzgründen tun, mit der nächsten Version überholt sein könnte.
Die Spaltenreihenfolge ist für mich fast immer sehr relevant, da ich routinemäßig generischen Code schreibe, der das Datenbankschema liest, um Bildschirme zu erstellen. Meine Bildschirme zum Bearbeiten eines Datensatzes werden fast immer erstellt, indem ich das Schema lese, um die Liste der Felder abzurufen und sie dann der Reihe nach anzuzeigen. Wenn ich die Reihenfolge der Spalten ändern würde, würde mein Programm immer noch funktionieren, aber die Anzeige könnte für den Benutzer seltsam sein. Sie erwarten, dass Name / Adresse / Stadt / Bundesland / Postleitzahl angezeigt wird, nicht Stadt / Adresse / Postleitzahl / Name / Bundesland. Sicher, ich könnte die Anzeigereihenfolge der Spalten in Code oder eine Steuerdatei oder so etwas einfügen, aber jedes Mal, wenn wir eine Spalte hinzufügen oder entfernen, müssen wir daran denken, die Steuerdatei zu aktualisieren. Ich mag es, Dinge einmal zu sagen. Wenn der Bearbeitungsbildschirm nur aus dem Schema erstellt wird, Das Hinzufügen einer neuen Tabelle kann bedeuten, dass keine Codezeilen geschrieben werden, um einen Bearbeitungsbildschirm dafür zu erstellen, was sehr cool ist. (Nun, okay, in der Praxis muss ich normalerweise einen Eintrag zum Menü hinzufügen, um das generische Bearbeitungsprogramm aufzurufen, und ich habe generell auf das generische "Auswählen eines zu aktualisierenden Datensatzes" verzichtet, da es zu viele Ausnahmen gibt, um es praktisch zu machen .)
quelle
Abgesehen von der offensichtlichen Leistungsoptimierung stieß ich auf einen Eckfall, in dem das Neuordnen von Spalten dazu führte, dass ein (zuvor funktionsfähiges) SQL-Skript fehlschlug.
Aus der Dokumentation "TIMESTAMP- und DATETIME-Spalten haben keine automatischen Eigenschaften, es sei denn, sie werden explizit angegeben, mit dieser Ausnahme: Standardmäßig enthält die erste TIMESTAMP-Spalte sowohl DEFAULT CURRENT_TIMESTAMP als auch ON UPDATE CURRENT_TIMESTAMP, wenn keine explizit angegeben ist" https: //dev.mysql .com / doc / refman / 5.6 / de / timestamp-initialization.html
Ein Befehl
ALTER TABLE table_name MODIFY field_name timestamp(6) NOT NULL;
funktioniert also, wenn dieses Feld der erste Zeitstempel (oder Datum / Uhrzeit) in einer Tabelle ist, aber nicht anders.Natürlich können Sie diesen Befehl alter so korrigieren, dass er einen Standardwert enthält, aber die Tatsache, dass eine Abfrage, die funktioniert hat, aufgrund einer Neuordnung der Spalten nicht mehr funktioniert, hat meinen Kopf verletzt.
quelle
Sie müssen sich nur dann um die Spaltenreihenfolge kümmern, wenn sich Ihre Software speziell auf diese Reihenfolge stützt. In der Regel ist dies auf die Tatsache zurückzuführen, dass der Entwickler faul geworden ist und a ausgeführt hat
select *
und dann in seinem Ergebnis nach Index und nicht nach Namen auf die Spalten verwiesen hat.quelle
Im Allgemeinen geschieht in SQL Server beim Ändern der Spaltenreihenfolge über Management Studio, dass eine temporäre Tabelle mit der neuen Struktur erstellt, die Daten aus der alten Tabelle in diese Struktur verschoben, die alte Tabelle gelöscht und die neue umbenannt werden. Wie Sie sich vorstellen können, ist dies eine sehr schlechte Wahl für die Leistung, wenn Sie einen großen Tisch haben. Ich weiß nicht, ob My SQL dasselbe tut, aber es ist ein Grund, warum viele von uns es vermeiden, Spalten neu zu ordnen. Da select * niemals in einem Produktionssystem verwendet werden sollte, ist das Hinzufügen von Spalten am Ende für ein gut gestaltetes System kein Problem. Die Reihenfolge der Spalten in der Tabelle sollte im Allgemeinen nicht beeinträchtigt werden.
quelle