MySQL-Partitionierung: Gibt es einen Leistungskompromiss zwischen der Anzahl der Partitionen und der Größe jeder Partition?

10

Ich habe eine große Tabelle (mehrere 100 Millionen Zeilen), die ich effizient partitionieren möchte. Meine Frage ist, ob es einen Kompromiss zwischen Partitionsgröße und Anzahl der Partitionen gibt. Soweit ich weiß, sind die meisten Abfragen in einer in der Partition verwendeten Spalte schneller, da die Abfrage (für die meisten Abfragen) nur innerhalb der für die Abfrage geltenden Partition suchen muss. Um die Effizienz zu maximieren, ist es daher sinnvoll, eine große Tabelle in die maximale Anzahl von Partitionen zu unterteilen, um jede Partition so klein wie möglich zu halten. Im Fall von MySQL bedeutet dies 1024 Partitionen. Aber gibt es einen Leistungsnachteil bei einer großen Anzahl von Partitionen? Wie findet man die optimale Anzahl von Partitionen?

Hinweis: Es gibt bereits eine etwas ähnliche Frage zum Stapelüberlauf , aber nur eine Antwort, die (aus meiner Sicht) die Marke verfehlt. Also werde ich die Frage auf meine eigene Weise stellen ... hoffentlich ist es klarer

Robguinness
quelle

Antworten:

6

Vergleichen wir sie

TEILUNGSGRÖSSE

Wenn Sie Folgendes haben:

  • 100 Millionen Zeilen in einer Tabelle
  • BTREE-Indizierung
  • Jede Seite im BTREE enthält 1024 Schlüssel

Wie würden die Metriken aussehen?

Da LOG (100000000) / LOG (2) = 26.575424759099, hätte ein BTREE-Index mit 1024 Schlüsseln pro Seite treenode eine Baumhöhe von nur 3 (CEILING (LOG (100000000) / LOG (1024))). Bei nur drei Seitenknoten würde eine binäre Suche nach dem benötigten Schlüssel in jedem Treenode, auf den zugegriffen wird, zu einem Beschneiden und Isolieren von etwa 30 Schlüsseln führen.

ANZAHL DER TEILUNGEN

Wenn Sie Folgendes haben:

  • 100 Millionen Zeilen in einer Tabelle
  • BTREE-Indizierung
  • Jede Seite im BTREE enthält 1024 Schlüssel
  • Sie erstellen 1024 Parititionen

Die Zahlen wären etwas anders.

Jede Partition sollte ungefähr 97656 Zeilen haben. Was würden die Metriken jetzt werden?

Da LOG (97656) / LOG (2) = 16.575421065795, hätte ein BTREE-Index mit 1024 Schlüsseln pro Seite treenode eine Baumhöhe von nur 2 (CEILING (LOG (97656) / LOG (1024))). Mit nur zwei Seitenknoten würde eine binäre Suche nach dem benötigten Schlüssel in jedem aufgerufenen Treenode zu einem Beschneiden und Isolieren von ungefähr 20 Schlüsseln führen.

FAZIT

Durch das Verteilen der Schlüssel wird nur eine Baumebene entfernt, es werden jedoch im Wesentlichen 1024 Indizes erstellt. Die Abfragen kennen den Unterschied nicht. Die Suchzeit wäre wahrscheinlich bestenfalls nominal zugunsten von Partitionen. Stellen Sie jedoch sicher, dass alle Daten aktiv sind. Andernfalls treffen Sie möglicherweise nur wenige Partitionen, während andere Partitionen mit Daten, auf die nur selten zugegriffen wird, nur Speicherplatz beanspruchen und nie häufig genug aufgerufen werden, um die Partitionierung zu rechtfertigen . Möglicherweise müssen Sie sich um andere Leistungsmetriken kümmern, die offensichtlicher sind (z. B. interne Defragmentierung in XFS , ext3 oder ext4 usw.). Sie müssen sich auch Gedanken darüber machen, welche Speicher-Engine Sie verwenden, weil:

  • Die InnoDB-Indizierung wäre im Vergleich zu MyISAM etwas unübersichtlicher, da ein Clustered-Index verwaltet werden muss
  • InnoDB schreibt Daten sowohl in ibdata1 als auch in der aktuellen Protokolldatei (ib_logfile0 oder ib_logfile1) doppelt.
RolandoMySQLDBA
quelle
1
Danke, RolandoMySQLDBA, das ist sehr interessant. Ich verstehe daraus, dass die Partitionierung einen kleinen, aber spürbaren positiven Einfluss auf die Abfragegeschwindigkeit hat, aber auch andere negative Auswirkungen haben kann, z. B. Fragmentierung. Was mich jedoch interessiert, ist, wie man die optimale Anzahl von Partitionen bestimmt. Sollte ich immer die maximal zulässige Anzahl verwenden (dh 1024), oder könnte eine andere Zahl ein guter Kompromiss zwischen den positiven und negativen Effekten sein? Oder ist es nicht möglich, diese Art der Optimierung zu analysieren?
Robguinness
Übrigens, dieser Artikel schlägt vor, dass die Antwort etwas komplizierter ist: mysqlperformanceblog.com/2010/12/11/…
Robguinness
Die Antwort ist gut, aber es geht um die Suche nach Schlüssel (oder indiziertem Feld). Ich habe nicht viel Erfahrung mit Partitionierung, aber aus meiner Sicht ist es nützlich, wenn Sie einen vollständigen Tabel-Scan durchführen müssen. In diesem Fall scannen Sie nur mehrere Partitionen anstelle der gesamten Tabelle.
Cherry