Indexoptimierung für Bereichsabfragen
Spalten mit höherer Kardinalität tragen zu effizienteren Indizes in MySQL bei. Bei Bereichsabfragen gilt jedoch eine Ausnahme.
Problemstellung
Betrachten Sie eine Tabelle mit der folgenden Struktur:
CREATE TABLE `files` ( `did` int(10) UNSIGNED NOT NULL DEFAULT '0', `filename` VARBINARY(200) NOT NULL, `ext` VARBINARY(5) DEFAULT NULL, `fsize` DOUBLE DEFAULT NULL, `filetime` DATETIME DEFAULT NULL, PRIMARY KEY (`did`,`filename`), KEY `fe` (`filetime`,`ext`), -- Option 1 KEY `ef` (`ext`,`filetime`) -- Option 2 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Filetimes sind unterschiedlich, während es eine begrenzte Anzahl von Ext-Werten gibt (d. h. höhere Kardinalität für Filetime, niedrigere Kardinalität für Ext). Eine Abfrage umfasst beide Spalten mit den folgenden Bedingungen:
WHERE ext = '...' AND filetime BETWEEN ... AND ...
Welcher Index, fe oder ef, ist optimaler?
Antwort
Überraschenderweise , ist der Index mit ext als erster Spalte trotz seiner geringeren Kardinalität hierfür effizienter Abfrage.
Erklärung
Der MySQL-Optimierer analysiert Indexalternativen und wählt diejenige mit den niedrigsten Kosten aus. Mithilfe des Optimierer-Trace können wir die Gründe für diese Wahl beobachten.
Zum Beispiel (filetime first) schätzt MySQL, dass es 16684 Zeilen scannen müsste, um „gif“-Dateien zu finden, selbst wenn die Bereichsbedingung aktiviert ist filetime.
Für ef (ext first) wird jedoch geschätzt, dass es beide Indexspalten verwenden und schnell einen Drilldown zu den entsprechenden Zeilen durchführen kann, was zu Kosten von nur führt 646,61. MySQL wählt diesen Index, da er mehr Schlüsselteile verwenden kann, was die Suche effizienter macht.
Schlussfolgerungen
Das obige ist der detaillierte Inhalt vonWelcher MySQL-Index ist für Bereichsabfragen effizienter: Führend mit Spalte mit hoher oder niedriger Kardinalität?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!