Warum bleibt die Kardinalität eines Index in MySQL unverändert, wenn ich einen neuen Index hinzufüge?

8

Ich habe einen FULLTEXT-Index wie folgt zu einer meiner MySQL-Datenbanktabellen hinzugefügt:

%Vor%

Das Problem ist, dass ich mit phpmyadmin die Kardinalität meines neuen Indexes nur 1 sehen kann. Bedeutet dies, dass der Index niemals verwendet wird?

Ich habe einen analyze table Befehl ausgeführt, aber es scheint nichts zu tun.

%Vor%

Die entsprechenden Typen der Indexfelder sind varchar (100), varchar (100), text, varchar (200) und die verwendete Engine ist MyISAM und die Tabelle hat ungefähr 30 000 Zeilen, die alle eindeutig sind. Meine MySQL Version ist 5.0.45.

Mache ich etwas falsch?

    
Tom 17.04.2009, 07:46
quelle

2 Antworten

13

Wenn Sie nur eine Zeile in der Tabelle haben, sollte die Kardinalität für den Index natürlich 1 sein. Es zählt nur die Anzahl der eindeutigen Werte.

Wenn Sie sich einen Index als Nachschlagetabelle vorstellen, die auf Buckets basiert (wie ein Hash), dann ist die Kardinalität die Anzahl der Buckets.

So funktioniert es: Wenn Sie einen Index über eine Gruppe von Spalten (a,b,c,d) erstellen, dann durchläuft die Datenbank alle Zeilen in der Tabelle und betrachtet die geordneten Quadrupel dieser 4 Spalten für jede Zeile. Angenommen, Ihre Tabelle sieht so aus:

%Vor%

Was die Datenbank betrachtet, sind also nur die 4 Spalten (a, b, c, d):

%Vor%

Sehen Sie, dass nur noch 3 eindeutige Zeilen übrig sind? Diese werden unsere Eimer, aber wir werden darauf zurückkommen. In Wirklichkeit gibt es auch eine Datensatz-ID oder Zeilenidentifikation für jede Zeile in der Tabelle. So sieht unsere ursprüngliche Tabelle so aus:

%Vor%

Wenn wir also nur die 4 Spalten von (a, b, c, d) betrachten, sehen wir uns auch die Zeilen-ID an:

%Vor%

Aber wir wollen nach (a, b, c, d) und nicht nach Zeilen-ID suchen, also erzeugen wir etwas wie folgt:

%Vor%

Und schließlich gruppieren wir alle Zeilen-IDs von Zeilen, die identische (a, b, c, d) -Werte haben:

%Vor%

Sehen Sie das? Die Werte von (a, b, c, d), die (1,1,1,1) (1,2,1,1) und (1,3,1,1) sind, sind Schlüssel für unsere Nachschlagetabelle geworden in die Zeilen der ursprünglichen Tabelle.

Tatsächlich passiert nichts davon wirklich, aber es sollte Ihnen eine gute Idee geben, wie eine "naive" (d. h. einfache) Implementierung eines Indexes durchgeführt werden könnte.

Aber das Entscheidende ist: Die Kardinalität misst nur, wie viele eindeutige Zeilen es in einem Index gibt. Und in unserem Beispiel war das die Anzahl der Schlüssel in unserer Nachschlagetabelle, die 3 war.

Hoffe das hilft!

    
scraimer 16.04.2009 11:07
quelle
8

Ich kann nicht definitiv antworten, warum MySQL die Kardinalität nicht berechnet, aber ich kann es erraten. Das MySQL-Handbuch lautet:

  

Kardinalität: Eine Schätzung der Anzahl der eindeutigen Werte im Index. Dies wird durch Ausführen von ANALYZE TABLE oder myisamchk -a aktualisiert. Die Kardinalität wird basierend auf Statistiken gezählt, die als Ganzzahlen gespeichert sind. Daher ist der Wert selbst für kleine Tabellen nicht unbedingt exakt. Je höher die Kardinalität, desto größer die Chance, dass MySQL den Index bei Joins verwendet.

FULLTEXT-Indizes werden nur in MATCH ... AGAINST-Abfragen (...) verwendet, wodurch der zu verwendende Index erzwungen wird. Die MATCH ... AGAINST-Syntax funktioniert nicht, wenn für diese Felder kein FULLTEXT-Index vorhanden ist.

Ich vermute, dass die Kardinalität nicht berechnet wird, weil wirklich nicht notwendig ist .

Beachten Sie, dass Suchen gegen den Index funktionieren, obwohl die Kardinalität nicht festgelegt ist.

Für den Datensatz scheint eine ANALYZE TABLE foobar-Anweisung die Kardinalität korrekt zu setzen.

    
Vegard Larsen 16.04.2009 11:44
quelle