mysql mehrspaltigen Index nicht funktioniert (wie erwartet)?
-
10-10-2019 - |
Frage
Ich habe eine Tabelle wie diese
CREATE TABLE IF NOT EXISTS `tbl_folder` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`owner_userid` int(11) NOT NULL,
`name` varchar(63) NOT NULL,
`description` text NOT NULL,
`visibility` tinyint(4) NOT NULL DEFAULT '2',
`num_items` int(11) NOT NULL DEFAULT '0',
`num_subscribers` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `owner_userid` (`owner_userid`),
KEY `vis_sub_item` (`visibility`,`num_subscribers`,`num_items`)
) ENGINE=InnoDB
da ich einen Index auf Sicht, NUM_SUBSCRIBERS und NUM_ITEMS haben, erwarte ich, dass nur die ersten 15 Zeilen müssen nur betrachtet werden, sondern ERKLÄREN sagt 55856 Zeilen. Irgendeine Idee? Dank
EXPLAIN SELECT t.id, name, description, owner_userid, num_items, num_subscribers
FROM `tbl_folder` `t`
WHERE visibility =2
ORDER BY `t`.`num_subscribers` DESC , `t`.`num_items` DESC
LIMIT 15
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t ref vis_sub_item vis_sub_item 1 const 55856 Using where
Lösung
Ihr 3-Feld-Index sieht gut aus und die EXPLAIN
verspricht.
Auch wenn es heißt "55856 Zeilen", die nur eine ist Schätzung von EXPLAIN
zur Verfügung gestellt.
Da key_len =1
, wissen Sie es das erste Byte Ihrer Verbindung Index als Gleichheit / Referenz ist mit.
Da es kein filesort in Ihrem Extra
Feld erwähnt ist, wissen Sie, dass die ORDER BY
/ Sortieranlagen ist durch den Index gehandhabt wird.
Wenn Sie Ihre handler_%
Sitzung Statistiken überprüfen, erhalten Sie eine bessere Vorstellung davon, wie viele Zeilen werden tatsächlich gelesen.
Side Gedanken:
Da Sie wissen, dass Sie letztlich zu Hit Platte gehen, um Ihre Zeilen abzurufen, wenn 99% Ihrer Daten visibility=2
hat (nur spekulieren), dann würden Sie wahrscheinlich als gleich gut / schnell Ergebnisse mit einer Verbindung Index nur auf num_subscribers
erhalten & num_items
. Oder wohl so gut / schnell, wenn Sie einen einzelnen Index auf num_subscribers
haben, je nachdem es die Mächtigkeit / Einzigartigkeit.
Andere Tipps
Ich glaube nicht, dass EXPLAIN
Blicke auf der OFFSET
oder LIMIT
Klausel. EXPLAIN
soll, um anzuzeigen, wie die Abfrage ausgeführt werden würde, welche Tasten er verwendet, wie Tabellen verknüpft sind, usw. Die LIMIT
Klausel ist wie eine Art Post-Abfrage Modifikator ... jetzt, dass wir wissen, was wir wollen, em nur geben die zuerst so viele. So enthält die Zeilen Feld die Anzahl der möglichen Zeilen, die in der Abfrage vorhanden sind. Von dort OFFSET
und LIMIT
würden die spezifisch diejenigen auswählen, die Sie wollen.
Ich bin herauszufinden, dass, wenn Sie Ihre SELECT
ohne EXPLAIN
ausgeführt, dann würden Sie die Anzahl der Datensätze erhalten Sie wollten.
Ja, das Problem ist, dass Ihr Index nicht korrekt ist. Ich meine, Sie indiziert alle drei Felder und Ihre Auswahlabfrage prüft nur für einen. In MySQL Indizierung 2 Reihen getrennt unterscheidet sich von der Indizierung 3 Reihen zusammen.
Versuchen
CREATE TABLE IF NOT EXISTS `tbl_folder` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`owner_userid` int(11) NOT NULL,
`name` varchar(63) NOT NULL,
`description` text NOT NULL,
`visibility` tinyint(4) NOT NULL DEFAULT '2',
`num_items` int(11) NOT NULL DEFAULT '0',
`num_subscribers` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `owner_userid` (`owner_userid`),
KEY `vis_index` (`visibility`),
KEY `vis_sub_item` (`num_subscribers`,`num_items`)
) ENGINE=InnoDB