NULL in MySQL (Leistung & Speicher)

75

Was genau macht null in Bezug auf Leistung und Speicher (Speicherplatz) in MySQL?

Zum Beispiel:

TINYINT: 1 Byte TINYINT mit NULL 1 Byte + speichert irgendwie NULL?

Steve
quelle

Antworten:

102

Dies hängt davon ab, welche Speicher-Engine Sie verwenden.

Im MyISAM-Format enthält jeder Zeilenkopf ein Bitfeld mit einem Bit für jede Spalte, um den NULL-Status zu codieren. Eine Spalte, die NULL ist, belegt immer noch Speicherplatz, sodass NULL-Speicher den Speicher nicht reduzieren. Siehe https://dev.mysql.com/doc/internals/en/myisam-introduction.html

In InnoDB hat jede Spalte einen "Feldstartversatz" im Zeilenkopf, der ein oder zwei Bytes pro Spalte beträgt. Das hohe Bit in diesem Feldstartversatz ist aktiviert, wenn die Spalte NULL ist. In diesem Fall muss die Spalte überhaupt nicht gespeichert werden. Wenn Sie also viele NULL-Werte haben, sollte Ihr Speicher erheblich reduziert werden. Siehe https://dev.mysql.com/doc/internals/en/innodb-field-contents.html

BEARBEITEN:

Die NULL-Bits sind Teil der Zeilenüberschriften. Sie können sie nicht hinzufügen.

Ich kann mir nur vorstellen, dass NULLs die Leistung verbessern, wenn in InnoDB eine Datenseite mehr Zeilen enthält, wenn die Zeilen NULLs enthalten. Ihre InnoDB-Puffer sind möglicherweise effektiver.

Ich wäre jedoch sehr überrascht, wenn dies in der Praxis einen erheblichen Leistungsvorteil bietet. Die Sorge um die Auswirkungen von NULL auf die Leistung liegt im Bereich der Mikrooptimierung. Sie sollten Ihre Aufmerksamkeit an anderer Stelle konzentrieren, in Bereichen, die mehr Geld kosten. Zum Beispiel das Hinzufügen ausgewählter Indizes oder das Erhöhen der Datenbank-Cache-Zuordnung.

Bill Karwin
quelle
Wird das Hinzufügen eines NULL-Bits die Suche beschleunigen? (Im Vergleich dazu, das Feld einfach leer zu lassen)
Steve
1
Weitere Inhalte nach "BEARBEITEN" finden Sie in meinem Kommentar oben.
Bill Karwin
4
@ Leistung: Wenn Sie einen Index für eine Spalte haben, dh NULL, benötigt MySQL mehr Logik zum Auswählen, Sortieren usw. Ich empfehle daher, NULL zumindest für indizierte Felder aus Leistungsgründen zu vermeiden.
Phil
@ BillKarwin Auf der offiziellen MySQL-Website wird erwähnt, dass Not Null in Leistung und Größe besser ist. Dev.mysql.com/doc/refman/5.5/en/data-size.html
Navrattan Yadav
@navy, ich empfehle Ihnen, einige Benchmarks durchzuführen, um zu bestätigen, wie viel oder wie wenig Unterschied zwischen der Verwendung von Nullen oder nicht Nullen besteht.
Bill Karwin
39

Bills Antwort ist gut, aber etwas veraltet. Die Verwendung von ein oder zwei Bytes zum Speichern von NULL gilt nur für das Zeilenformat InnoDB REDUNDANT. Da MySQL 5.0.3 InnoDB das Zeilenformat COMPACT verwendet, das nur ein Bit zum Speichern eines NULL verwendet (natürlich ist ein Byte das Minimum), gilt Folgendes:

Erforderlicher Speicherplatz für NULL-Werte = CEILING-Bytes (N / 8), wobei N die Anzahl der NULL-Spalten in einer Zeile ist.

  • 0 NULL = 0 Bytes
  • 1 - 8 NULL = 1 Byte
  • 9 - 16 NULL = 2 Bytes
  • 17 - 24 NULL = 3 Bytes
  • etc...

Laut der offiziellen MySQL-Site über COMPACT vs REDUNDANT:

Das kompakte Zeilenformat verringert den Zeilenspeicherplatz um etwa 20% auf Kosten einer erhöhten CPU-Auslastung für einige Vorgänge. Wenn Ihre Arbeitslast typisch ist und durch die Cache-Trefferquote und die Festplattengeschwindigkeit begrenzt ist, ist das kompakte Format wahrscheinlich schneller.

Vorteil der Verwendung von NULL gegenüber leeren Zeichenfolgen oder Nullen:

  • 1 NULL benötigt 1 Byte
  • 1 Leerer String benötigt 1 Byte (vorausgesetzt VARCHAR)
  • 1 Null benötigt 4 Bytes (unter der Annahme von INT)

Hier sehen Sie die Einsparungen:

  • 8 NULL-Werte erfordern 1 Byte
  • 8 leere Zeichenfolgen erfordern 8 Bytes
  • 8 Nullen erfordern 32 Bytes

Andererseits schlage ich vor, NULL-Werte über leeren Zeichenfolgen oder Nullen zu verwenden, da diese organisierter und portabler sind und weniger Speicherplatz benötigen. Um die Leistung zu verbessern und Platz zu sparen, konzentrieren Sie sich auf die Verwendung der richtigen Datentypen, Indizes und Abfragen anstelle von seltsamen Tricks.

Weitere Informationen finden Sie unter : https://dev.mysql.com/doc/refman/5.7/en/innodb-physical-record.html

Arian Acosta
quelle
Wie ich aus Ihrer Antwort verstanden habe, ist die Optimierung in MySQL eingebettet. und ich sollte nichts tun, nur mysql 5.0.3 oder höher zu verwenden ist genug?
Ammar Bozorgvar
@ ammar-bozorgvar Ja, diese werden bei Verwendung von InnoDB standardmäßig intern von MySQL ausgeführt. Dies ist die offizielle Dokumentation Link . Viel Glück!
Arian Acosta
Ich bin ein wenig verwirrt: Bill sagte, dass "das hohe Bit in diesem Feld Startversatz aktiviert ist, wenn die Spalte NULL ist. In diesem Fall muss die Spalte überhaupt nicht gespeichert werden", und Sie sagten "8 NULL" benötigen 1 Byte ". Nehmen Nullen Platz oder nicht? Danke
bylijinnan
1
Jetzt verstehe ich: 8 NULL-Werte erfordern 1 Byte IN RECORD HEADER, aber NULL-Werte werden nicht gespeichert.
Bylijinnan
6

Ich würde Bill Karwin zustimmen, obwohl ich diese MySQL-Tipps hinzufügen würde . Nummer 11 spricht dies speziell an:

Fragen Sie sich zunächst, ob es einen Unterschied zwischen einem leeren Zeichenfolgenwert und einem NULL-Wert gibt (für INT-Felder: 0 und NULL). Wenn es keinen Grund gibt, beides zu haben, benötigen Sie kein NULL-Feld. (Wussten Sie, dass Oracle NULL und leere Zeichenfolge als gleich betrachtet?)

NULL-Spalten benötigen zusätzlichen Speicherplatz und können Ihre Vergleichsanweisungen komplexer gestalten. Vermeiden Sie sie einfach, wenn Sie können. Ich verstehe jedoch, dass einige Leute möglicherweise ganz bestimmte Gründe haben, NULL-Werte zu haben, was nicht immer schlecht ist.

Andererseits verwende ich immer noch null für Tabellen, die nicht viele Zeilen enthalten, hauptsächlich, weil mir die Logik gefällt, NICHT NULL zu sagen.

Update Wenn ich das später noch einmal betrachte, möchte ich hinzufügen, dass ich persönlich nicht gerne 0 anstelle von NULL in der Datenbank verwende, und ich empfehle es nicht. Dies kann leicht zu vielen Fehlalarmen in Ihrer Anwendung führen, wenn Sie nicht vorsichtig sind.

Kapitän Hypertext
quelle
1

dev.mysql.com/doc/refman/5.0/de/is-null-optimization.html

MySQL kann für col_name IS NULL dieselbe Optimierung durchführen, die es für col_name = constant_value verwenden kann. Beispielsweise kann MySQL Indizes und Bereiche verwenden, um mit IS NULL nach NULL zu suchen

Chu Khanh Van
quelle