Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Warum ist die durchschnittliche Zeilenlänge viermal so groß wie erwartet?

Es gibt viele Gründe für eine hohe durchschnittliche Zeilengröße.

  • Es ist eine Annäherung. (Ich habe festgestellt, dass es normalerweise 2x-3x hoch ist.) In einem extremen Fall – eine Zeile in der Tabelle – beansprucht es 16384 Bytes pro Zeile. Das ist ein InnoDB-Block. Die Anzahl der Zeilen in der Tabelle ist geschätzt . Der für die Zeilen verwendete Speicherplatz ist exakt, siehe Overheads unten. Die durchschnittliche Zeilengröße ist der Quotient dieser beiden.

  • Overhead pro Spalte – 1 oder 2 Bytes

  • Overhead pro Zeile – 20-30 Bytes – für die Abwicklung von Transaktionen, das Suchen von Zeilen in einem Block usw.

  • Overhead pro Block – einige Bytes pro 16-KB-Block

  • Overhead für das Thrashing in einem BTree -- min ist etwa 1/16 eines Blocks, max ist etwa die Hälfte des Blocks, der Durchschnitt liegt bei etwa 30 % nach vielen Löschungen und/oder zufälligen Einfügungen.

  • Overhead für die Vorabzuweisung von Speicherplatz (1 MB? 8 MB?)

  • Wenn eine Tabelle durch das Einpassen in einen Block wächst, verschiebt sich der Layoutalgorithmus und der Prozentsatz des Overheads steigt vorübergehend an.

  • Gelöschte Zeilen geben ihren Speicherplatz nicht an das Betriebssystem zurück, sodass die Dateigröße konstant bleibt, wodurch die scheinbare erhöht wird Zeilengröße.

  • Wenn Sie keinen expliziten PRIMARY KEY haben oder ein UNIQUE Schlüssel, der zum PK hochgestuft werden kann, dann gibt es ein unzugängliches 6-Byte-Feld (pro Zeile) für den PK.

  • Großer TEXT /BLOB und sogar VARCHAR werden „off-record“ gespeichert. Das erschwert die Berechnungen erheblich. Und es ist abhängig von welchem ​​der 4 ROW_FORMATs du benutzt. In einigen Fällen gibt es einen 20-Byte-"Zeiger" für jede solche Zelle.

  • FOREIGN KEY Beschränkungen erhöhen nicht den erforderlichen Platz, außer dass sie können Erzwingen Sie die Erstellung eines Indexes.

  • INDEXes , außer dem PRIMARY KEY sind nicht in avg_row_length enthalten.

  • Der PRIMARY KEY normalerweise beinhaltet sehr wenig Overhead in den Daten BBaum. Eine einfache Faustregel ist 1 % Overhead (über der Spalte selbst). Dieser Overhead sind die Nicht-Blatt-Knoten des BTree.

  • Während eine InnoDB-Transaktion beschäftigt ist, werden alle geänderten Zeilen in der "Verlaufsliste" festgehalten. Dies führt zu mehr Overhead.

  • (Nicht ganz verwandt). COMPRESSED von InnoDB hat Probleme - es gibt nur etwa 2x Komprimierung, im Gegensatz zu einer typischen Textkomprimierung von 3x. Es kostet etwas RAM, weil sowohl die komprimierten als auch die unkomprimierten Daten gleichzeitig im Buffer_pool sein müssen (zumindest für einige Blöcke).

SHOW TABLE STATUS und Abrufen von information_schema.TABLES liefert die gleichen Daten. Es gibt Möglichkeiten, einige zu bekommen Einblick in die Tiefe des B+Tree für die Daten und für jede Tabelle.