MySQL: Macht die Reihenfolge der Felder in einer Tabelle einen Unterschied in der Leistung?

7

Insbesondere frage ich mich, ob ich alle meine Felder mit fester Länge wie int, timestamp, char am Anfang der CREATE TABLE und die gesamte variable Länge wie varcharam Ende platzieren soll.

Ich frage mich auch, ob TEXTFelder anders behandelt werden.

Bryan Field
quelle
Ich habe das MySQL-Tag für diese Frage entfernt, da Kommentare zu anderen RDBMS unterschiedliche Perspektiven für die Reihenfolge der Tabellenspalten haben können, an die niemand für MySQL gedacht hat. Trotzdem ist dies eine ausgezeichnete Frage (+1) an DBA.SE und andere DB Gurus.
RolandoMySQLDBA

Antworten:

2

Abhängig von der RDBMS-Speicher-Engine werden die Felder möglicherweise intern für die Speicherung und Anzeige neu angeordnet. Wenn wir diese Frage aus dem Blickwinkel eines C-Programms betrachten, ist eine Tabelle in einer Datenbank wie eine C-Struktur. Beispiel: Eine Tabelle in einem AC-Programm könnte folgendermaßen aussehen:

typedef struct _Table {
  char type,      /* 1 byte   */
  int id,         /* 4 bytes  */
  char *name;     /* 4 bytes  */
  char city[25];  /* 25 bytes */ 
} Table;          /* 34 bytes total */

Sie können sehen, dass Sie in Ihrem Programm erwarten, dass sich Ihr erstes Strukturelement an der ersten Zeigerposition befindet, und dass ein Byte mehr Ihre zweite Elementposition usw. ist. Diese werden als Offsets bezeichnet.

Ihr RDBMS speichert die Dateidatenstruktur wahrscheinlich in einer Struktur im AC-Stil, damit es verstehen kann, wie die Offsets (Speicherorte) der Daten für jede Zeile aussehen. Dann werden Indizes angewendet, um die Suche zwischen ähnlichen Gruppen von Zeilen durchzuführen. Eine Indexposition ist einfach ein Zeiger auf das erste Byte jeder übereinstimmenden Zeile (oder Struktur).

Als Softwareentwickler möchten Sie die Struktur wahrscheinlich so packen, dass die kleinsten Datentypen am Anfang der Struktur stehen, damit Sie beim Durchsuchen Ihrer Zeigerarithmetik schneller zu Schlussfolgerungen gelangen. Dies ist jedoch eine Entwurfsentscheidung .

Unter dem Strich heißt es in der Best Practice, Ihr Modell vom kleinsten zum größten zu entwerfen, aber es wird wahrscheinlich trotzdem durch die Anforderungen der Speicher-Engine neu organisiert.

randomx
quelle
Ich denke, Sie haben vergessen hinzuzufügen, dass es auch ein bisschen
überoptimiert ist
2

Ich würde es wagen, in Bezug auf den Tisch vorne nein zu sagen. Die Reihenfolge der Felder in einem Index und die Anzahl der Felder in einem WHERE spielen jedoch eine große Rolle.

Beispiel: Sie haben folgende Tabelle:

CREATE TABLE testtable
(
    a INT,
    b INT,
    c INT,
    KEY (a,b,c)
);

Beachten Sie diese Abfrage:

SELECT * FROM testtable WHERE a=1 AND b=2 AND c=3;

Da jede Spalte in der WHERE-Klausel als eq_ref, auch bekannt als equa-reference (using =), erwähnt wird, kann der Index verwendet werden, um eine Spalte auf Null zu setzen.

Beachten Sie diese Abfrage:

SELECT * FROM testtable WHERE a=1 AND b>2 AND c=3;

Spalte a steht als eq_ref vor dem Index, Spalte b jedoch nicht. Dies ist eine Bereichsabfrage. Abhängig von der Kardinalität von Spalte a (Kardinalität in SHOW INDEXES FROM testtable sichtbar) wird ein Index-Scan durchgeführt, wenn die Kardinalität von a = 1 sehr niedrig ist und die Gesamtzahl der Zeilen mit Spalte a = 1 weniger als 5% der Anzahl der Zeilen beträgt Andernfalls wird in testtable ein vollständiger Tabellenscan von einem beliebigen Abfrageoptimierer (MySQL, Oracle, PostgreSQL, SQL Server usw.) ausgewählt.

Beachten Sie diese Abfrage:

SELECT * FROM testtable WHERE b=>2 AND c=3;

Diese WHERE-Klausel erwähnt niemals Spalte a. Ergebnis? automatischer vollständiger Tabellenscan.

In Bezug auf die Reihenfolge der Spalten in einer Tabelle kann das Defragmentieren von Tabellen und das Erstellen von Tabellenformaten mit festen Zeilenlängen mögliche Probleme bei der Reihenfolge der Tabellenspalten verringern. Dies ist ein vermutetes Problem.

Wenn jemand Probleme mit Oracle, PostgreSQL, SQL Server oder anderen RDBMS bezüglich der Reihenfolge der Tabellenspalten kennt, melden Sie sich bitte an.

RolandoMySQLDBA
quelle
Sie haben vergessen zu erwähnen, wie die Reihenfolge des Wo durch die Anzahl der zurückgegebenen Übereinstimmungen bestimmt werden soll. Das heißt, wenn c=1500.000 Datensätze zurückgegeben werden und c=3nur 15 Datensätze zurückgegeben werden, sollte c = 3 an erster Stelle in der WHEREKlausel stehen.
Vol7ron