Besetzt ein leerer Spaltenwert denselben Speicherplatz wie ein gefüllter Spaltenwert?


15

Ich habe eine Tabelle mit 2 Spalten. Der Typ beider Spalten ist auf festgelegt varchar(38). Wenn ich eine Zeile mit einem leeren Wert für eine der Spalten erstelle, wird derselbe Speicherplatz beansprucht, als ob der Wert nicht leer wäre?

Mit anderen Worten, reserviert MySQL Speicherplatz für die Spalte (abhängig vom Typ), wenn eine Zeile erstellt wird?

Antworten:


11

In der physischen Zeilenstruktur von Innodb Punkt 7 unter REDUNDANT ROW_FORMAT

Ein SQL-NULL-Wert reserviert ein oder zwei Bytes im Datensatzverzeichnis. Außerdem reserviert ein SQL-NULL-Wert null Byte im Datenteil des Datensatzes, wenn er in einer Spalte variabler Länge gespeichert wird . In einer Spalte mit fester Länge wird die feste Länge der Spalte im Datenteil des Datensatzes reserviert. Wenn der feste Platz für NULL-Werte reserviert wird, kann die Spalte von NULL auf einen Nicht-NULL-Wert aktualisiert werden, ohne dass die Indexseite fragmentiert wird.

In der physischen Zeilenstruktur von Innodb Aufzählungspunkt 2 unter COMPACT ROW_FORMAT

Der Teil mit variabler Länge des Datensatzkopfs enthält einen Bitvektor zum Anzeigen von NULL-Spalten. Wenn die Anzahl der Spalten im Index NULL sein kann, belegt der Bitvektor CEILING (N / 8) Bytes . (Wenn beispielsweise 9 bis 15 Spalten NULL sein können, verwendet der Bitvektor zwei Bytes.) Spalten, die NULL sind, belegen keinen anderen Platz als das Bit in diesem Vektor . Der Teil der Kopfzeile mit variabler Länge enthält auch die Längen der Spalten mit variabler Länge. Jede Länge nimmt ein oder zwei Bytes in Anspruch, abhängig von der maximalen Länge der Spalte. Wenn alle Spalten im Index NICHT NULL sind und eine feste Länge haben, enthält der Datensatzkopf keinen Teil mit variabler Länge.

Basierend auf diesen Aufzählungspunkten wird im Folgenden erläutert, was ein NULLWert für den Speicher einer Spalte in Anspruch nimmt

  • variable Länge: Ein NULL-Wert belegt keinen Speicher in der Zeile
  • Feste Länge: Nimmt den reservierten Platz ein

Jetzt müssen Sie sich zwischen der Verwendung von CHAR und VARCHAR entscheiden, da der erste Punkt ausgeführt wurde

Wenn der feste Platz für NULL-Werte reserviert wird, kann die Spalte von NULL auf einen Nicht-NULL-Wert aktualisiert werden, ohne dass die Indexseite fragmentiert wird

Dadurch wird verhindert, dass eine Fragmentierung einer Zeile die Straße entlanggeht, sobald Nicht-NULL-Daten gespeichert sind. Dies ist etwas, was ich zuvor in Bezug auf MyISAM besprochen habe: Siehe meinen alten Beitrag Was ist die Auswirkung der Verwendung von CHAR gegenüber VARCHAR auf ein Feld mit fester Größe? .


Hallo Rolando, es gab noch einen Punkt, den ich vergessen habe zu erwähnen, den Unterschied in der Speicherzuordnung zwischen einer varchar (5) und einer varchar (100) Typdeklaration. Oder wirklich die Strafe, die durch Überallokation entsteht.
Craig Efrein

@CraigEfrein Sie sollten Ihrer Antwort auf jeden Fall eine Speicherzuordnung hinzufügen. (Übrigens habe ich Ihre Antwort bereits positiv bewertet)
RolandoMySQLDBA

1
Die Strafe für SELECTeine Überzuweisung tritt auf, wenn Sie einen Komplex haben , der eine temporäre Tabelle erstellen muss. Wenn möglich, wird es verwenden MEMORY, und konvertieren VARCHARzu CHARfür die tmp - Tabelle. Nimmt jetzt VARCHAR(100)feste 100 (oder 300) Bytes und verlangsamt dadurch möglicherweise die Abfrage.
Rick James

@RolandoMySQLDBA, Ist das in Ihrer Antwort erläuterte Verhalten auf die Zeilenformate Mysql 5.7 DYNAMIC und COMPACT anwendbar?
Dinesh Kumar

@DineshKumar Diese Absätze befinden sich noch in den Dokumenten 5.7 / 8.0. Weitere Informationen zu DYNAMIC finden Sie unter dev.mysql.com/doc/refman/5.7/de/innodb-row-format-dynamic.html.
RolandoMySQLDBA

8

Unabhängig von der Länge, die Sie für Ihre varchar-Spalte definieren, ist der von einer leeren Spalte belegte Speicherplatz derselbe.

Die Typen CHAR und VARCHAR

Bildbeschreibung hier eingeben

Dies bezieht sich nur auf den von der varchar-Spalte belegten Speicherplatz und nicht auf den von der Zeile, ihren Indizes, Primärschlüsseln und anderen Spalten belegten Gesamtspeicherplatz.

Wie Ypercube in seinem Kommentar erwähnt, gibt es zusätzliche Überlegungen für den Zeilenspeicher als Ganzes, wenn mindestens eine nullfähige Spalte vorhanden ist.

Innodb physikalische Zeilenstruktur

Der Teil mit variabler Länge des Datensatzkopfes enthält einen Bitvektor zum Anzeigen von NULL-Spalten. Wenn es 9 bis 15 Spalten gibt, die NULL sein können, verwendet der Bitvektor zwei Bytes.)

...

Der Teil der Kopfzeile mit variabler Länge enthält auch die Längen der Spalten mit variabler Länge. Jede Länge nimmt ein oder zwei Bytes in Anspruch, abhängig von der maximalen Länge der Spalte. Wenn alle Spalten im Index NICHT NULL sind und eine feste Länge haben, enthält der Datensatzkopf keinen Teil mit variabler Länge

Und ja, der verwendete Speicherplatz ändert sich je nach ausgewähltem Typ, ob fest oder variabel, der Sortierung und anderen Faktoren wie der Engine.

MySQL gibt hier Empfehlungen zur Optimierung der Datenspeicherung: Optimieren der Datengröße

Aktualisieren

Eine zusätzliche Überlegung mit varchar und das ist Speicher. In MySQL ist es wichtig, die Größe einer Spalte mit variabler Länge so weit wie möglich zu begrenzen. Obwohl die Spalte variabel ist und der verwendete Speicherplatz variabel ist, reserviert MySQL Speicher in festen Blöcken, um Werte zu speichern. Zum Beispiel verwendet varchar (200) mehr Speicher als varchar (5). Dies ist kein Speicherplatzproblem, muss jedoch bei der Definition der Spalten berücksichtigt werden.


Die obigen Zahlen setzen CHARACTER SETlatin1 oder ascii voraus . Für utf8 ist Speicherplatz CHAR(4)12 erforderlich .
Rick James
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.