2016-07-19 3 views
1
  1. Ich verwende die InnoDB-Engine auf MySQL 5.7.MySQL - Ungleichmäßige Verteilung von Daten in Partitionen bei Verwendung der Schlüsselpartitionierung

  2. Ich habe eine Tabelle, in der eine der Spalten ein (nicht eindeutiger) dreibuchstabiger Ländercode ist (z. B. "SGP" für Singapur, "JPN" für Japan usw.).

  3. Für die meisten meiner Abfragen dieser Spalte Ländercode ist die erste Klausel WHERE I (z WHERE COUNTRY_CODE = 'SGP')

  4. Daher filtern, ich will nach dieser Spalte der Tabelle zu (Teil-) Partition. Da die meisten meiner Abfragen auf einem einzelnen Ländercode basieren, werden sie nur eine Partition auf diese Weise treffen.

  5. Aufgrund der großen Anzahl der verschiedenen Ländercodes möchte ich jedoch nicht die LIST-Partitionierung verwenden, bei der ich explizit auf jeden einzelnen Ländercode eingehen muss.

  6. Also habe ich KEY Partitionierung mit 8 Partitionen verwendet. Ich dachte, dass die Schlüsselpartitionierung, bei der der Wert hashed wird, mir eine mehr oder weniger gleichmäßige Verteilung über die 8 Partitionen geben würde (muss nicht perfekt sein).

  7. Was ich jedoch erlebt habe, ist, dass von den 8 Partitionen 4 von ihnen völlig unberührt sind. Dieses

ist ein Auszug aus meiner CREATE TABLE-Anweisung:

CREATE TABLE TBL_EATING_PLACES (
    ID INT UNSIGNED AUTO_INCREMENT NOT NULL, 
    TYPE_OF_FOOD SMALLINT UNSIGNED NOT NULL, 
    SUBTYPE_OF_FOOD SMALLINT UNSIGNED NOT NULL, 
    COUNTRY_CODE CHAR(3) NOT NULL, 
    ADDRESS VARCHAR(255), 
    ... 
    OTHER_NON_RELEVANT_COLUMNS ..., 
    ..., 
    CONSTRAINT PKEY PRIMARY KEY (ID, TYPE_OF_FOOD, SUBTYPE_OF_FOOD, COUNTRY_CODE) 
) 
ENGINE = InnoDB 
PARTITION BY LIST COLUMNS(TYPE_OF_FOOD, SUBTYPE_OF_FOOD) SUBPARTITION BY KEY(COUNTRY_CODE) SUBPARTITIONS 8 (
    PARTITION P_1_1 VALUES IN ((1, 1)), 
    PARTITION P_1_2 VALUES IN ((1, 2)), 
    PARTITION P_2_1 VALUES IN ((2, 1)), 
    PARTITION P_1_2 VALUES IN ((2, 2)), 
    PARTITION P_1_3 VALUES IN ((2, 2)), 
); 

Gibt es etwas falsch mit, wie ich den KEY Partitionierung machte, so dass es nur die Hälfte der Partitionen schlagen endete?

+0

Aber funktioniert es tatsächlich so? Wenn ich Ihre Partitionen richtig verstanden habe, müssen Sie tatsächlich mehrere Partitionen lesen, in denen Sie nach dem Ländercode suchen (weil Tabellen zuerst durch TYPE_OF_FOOD, SUBTYPE_OF_FOOD partitioniert werden). – e4c5

+0

ja, es tut mir leid, ich habe das Problem vereinfacht und gezoomt. Alle meine Abfragen werden zuerst nach TYPE_OF_FOOD und SUBTYPE_OF_FOOD gefiltert (dies ist implizit und der Frontend-Benutzer wird nicht einmal wählen können). Und dann gibt es eine Wahl nach COUNTRY_CODE zu filtern, die ich für die meisten meiner Verwendung normalerweise mache. Ich habe die (primäre) Partitionierung nicht näher ausgeführt, weil ich beobachtet habe, dass es gut funktioniert (d. H. Daten gehen in die richtige Partition). –

+0

nur ein Gedanke, ich bin mir nicht sicher, wie MySQL das Hashing tut, und nicht sicher, ob es relevant ist ... aber beeinflusst "lexikalische Nähe", ob zwei Werte in die gleiche Partition gehashed werden? (z. B. Schweiz (CHE) und China (CHN) und Australien (AUS) und Österreich (AUT)), und gibt es überhaupt eine Möglichkeit zu sehen, welche Zeilen in welchen Partitionen liegen? –

Antwort

1

Was ist falsch an der Schlüsselpartitionierung? Es bietet keinen Nutzen. Benutze es nicht. Stellen Sie stattdessen geeignete zusammengesetzte Indizes bereit, die Ihren Abfragen entsprechen.

(Hinzugefügt Fragen in den Kommentaren zur Adresse ...)

Normalerweise wird ein Composite-Index das Äquivalent tun kann, was Partitionierung der Fall ist. Der "Partitionsschlüssel" macht "Partitionsbereinigung", um die eine (oder die wenigen) Partitionen auszuwählen, in die man schauen kann. Wenn Sie den "Partitionsschlüssel" als erste Spalte in einem Index haben, erhalten Sie den gleichen Effekt. (Ja, es gibt Ausnahmen.)

Partitionen haben einige Overhead. Jede Partition ist eine Datei; das Öffnen von Dateien ist teuer. In einigen Fällen werden alle Partitionen vor der Bereinigung geöffnet. Früher gab es keinen Schnitt auf INSERT. (Yuck!) (Einige dieser Probleme wurden in der neueren Version behoben, aber es gibt noch einige Gemeinkosten.)

Ich habe mir viele Beispiele für Subpartitionierung und Nicht-RANGE-Partitionierung angesehen. Ich habe nur 4 Fälle gesehen, in denen die Indexierung nicht so gut ist wie die Partitionierung. Ich nehme an, dass Sie mein Blog gefunden haben, das die 4 auflistet. Hier ist eine Kopie: Partition Maintenance.

Eine 2-dimensionale Suche muss "den Suchraum reduzieren". Dies ist einer der 4 Fälle. Die RANGE-Partitionierung behandelt eine Dimension, die PRIMARY KEY die andere. Das funktioniert effizient (aber mit unordentlichem Code) zu Find the 10 nearest pizza parlors.

BY RANGE ist die einzige Partitionierung, die mit einem "Bereich" von Werten (z. B. einem Datumsbereich) umgehen kann.HASH sucht einfach alle die Partitionen.

VON LISTE kann genauso gut sein wie BY RANGE, aber nur für genaue Werte. Und dann gehe ich zurück zu sagen: "Warum nicht den Partitionsschlüssel vor den Index setzen, den Sie sonst benutzen würden"!

Ich werde gerne meinen Blog erweitern, wenn jemand einen 5. Anwendungsfall finden kann, für den ich keine gleichwertige Leistung ohne Partitionierung bereitstellen kann.

+0

Hi @ rick-james, als ich über dieses Thema gegoogelt habe, bin ich auf deine Blogs gestoßen, und ich muss sagen, dass deine Artikel sehr aufschlussreich sind! Es gibt einige Punkte, die ich nicht verstehe (nicht sicher, ob Sie das hier erklären können). (a) Warum ist die Partitionierung für die Performance generell nutzlos? Intuitiv, wenn es den Suchraum reduziert, sollte es mindestens so effektiv wie ein Index sein, nein? (b) Warum ist die Subpartitionierung nutzlos (reduziert den Suchraum weiter, nein?) (c) Warum ist eine KEY- oder HASH-Partitionierung im Vergleich zu RANGE nicht sinnvoll? (d) Was ist mit LIST Partitionierung (scheint identisch mit RANGE)? –

+0

Ich erweiterte meine Antwort. Vielleicht habe ich alle deine Fragen abgedeckt? –

+0

Danke rick-james für die Erklärungen! Ich bin überrascht, dass (a) alle Partitionen vor dem Beschneiden geöffnet werden (oh warum?), Und (b) mit Partitionierung von HASH (und wohl auch von KEY), werden alle Partitionen durchsucht (was ist dann der Sinn der Hashing?) –