Warum entscheidet sich MySQL für den falschen Index?

10

Ich habe eine partitionierte Tabelle in MySQL, die so aussieht:

%Vor%

Und das ist eine typische SELECT-Abfrage in der Tabelle:

%Vor%

Wenn Sie eine Erläuterung dazu machen, entscheidet sich MySQL manchmal dafür, PRIMARY anstelle von index1 zu verwenden. Dies scheint ziemlich konsistent zu sein, wenn Sie eine erste Erklärung geben. Nach ein paar wiederholten Erklärungen beschließt MySQL jedoch, den Index zu verwenden. Das Problem ist, dass diese Tabelle Millionen von Zeilen enthält und dass Einfügungen und Auswahlvorgänge sie in der Größenordnung von mehreren Malen pro Sekunde treffen. Die Auswahl des falschen Index führte dazu, dass diese SELECT-Abfragen nicht länger als eine Sekunde, sondern bis zu 40 Sekunden dauerten. Ich kann die Ausfallzeit nicht wirklich einplanen, daher kann ich keine Optimierung für die Tabelle ausführen (wegen der Größe würde das wahrscheinlich lange dauern) und bin mir nicht sicher, ob es in diesem Fall trotzdem helfen würde.

Ich habe das behoben, indem ich den Index erzwang, also sieht das so aus:

%Vor%

Wir führen dies auf MySQL 5.1.63 aus, von dem wir im Moment nicht wegkommen können.

Meine Frage ist, warum wählt MySQL den falschen Index? Und gibt es etwas, das getan werden kann, um es zu beheben, abgesehen von dem Erzwingen des Index für alle Abfragen? Partitioniert die Partitionierung die InnoDB-Engine? Ich habe viel mit MySQL gearbeitet und dieses Verhalten noch nie zuvor gesehen. Die Abfrage ist so einfach wie möglich, und der Index ist auch eine perfekte Übereinstimmung. Wir haben viele Abfragen, die davon ausgehen, dass der DB-Layer das Richtige tut, und ich möchte nicht alle durchgehen, um den richtigen Index zu verwenden.

Update 1:

Dies ist die typische Erklärung ohne die FORCE INDEX-Klausel. Sobald diese eingefügt ist, zeigt die Spalte mit den möglichen Schlüsseln nur den erzwungenen Index an.

%Vor%     
mjuarez 19.01.2013, 12:02
quelle

2 Antworten

3

Ich bin mir nicht 100% ig sicher, aber ich denke, das klingt logisch:

Sie partitionieren Ihre Tabelle BY RANGE (to_days(created_at)) . Das Feld created_at ist Teil des primary_key. Ihre Select-Abfragen verwenden den anderen Teil des Primärschlüssels. Auf diese Weise denkt die Serveroptimierungs-Engine, dass dies der schnellste Index wäre - unter Verwendung der Partition und des id -Primärteils.

Ich schlage vor (ohne den wahren Grund zu kennen, der zu Ihrer Wahl führte), Ihren Partitionsbereich auf die ID zu ändern und die Reihenfolge Ihres index1-Schlüssels zu ändern.

Weitere Informationen zur Partitionierung finden Sie unter

    
Bastian Rang 28.01.2013, 12:34
quelle
1

Ich bin nicht sicher, warum die Engine den falschen Index auswählen würde. Ich würde denken, dass ein Index, der einen EQUALITY-Test hat, den eines mit einem & gt; & lt; oder Reichweite. Eine andere Option, die den korrekten Index erzwingen könnte, wäre jedoch, einen "berechneten" Wert für die andere ID-Spalte zu erzwingen, sodass die Engine möglicherweise keine direkte Korrelation mit dem Index herstellen kann ... Etwas wie

%Vor%

wurde in

geändert %Vor%     
DRapp 28.01.2013 12:21
quelle