mysql più indice di colonna non funziona (come previsto)?
-
10-10-2019 - |
Domanda
Ho una tabella come questo
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
dal momento che ho un indice sulla visibilità, NUM_SUBSCRIBERS e NUM_ITEMS, mi aspetto che solo le prime 15 righe devono solo essere guardato, invece, SPIEGARE dice 55856 righe. Qualche idea? Grazie
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
Soluzione
Il tuo indice 3 campo sembra buona e il EXPLAIN
è promettente.
Anche se si dice "55856 righe", che è solo un stima fornito da EXPLAIN
.
Dal key_len =1
, si sa che sta utilizzando il primo byte del tuo indice composto come uguaglianza / di riferimento.
Dal momento che non v'è alcun filesort menzionato nel vostro campo Extra
, si sa che il ORDER BY
/ smistamento è affidate dall'indice.
Se si controlla le statistiche handler_%
sessione, si avrà una migliore idea di quante righe sono in realtà essere di lettura.
Pensieri collaterali:
Dal momento che sai che stai in ultima analisi, andando a colpire su disco per recuperare i file, se il 99% dei dati ha visibility=2
(solo speculando), si sarebbe probabilmente ottenere come altrettanto buono / risultati veloci con un indice composto solo su num_subscribers
& num_items
. O forse come buono / veloce se si ha un unico indice su num_subscribers
, a seconda di essa la cardinalità / unicità.
Altri suggerimenti
Non credo che sembra EXPLAIN
presso la clausola OFFSET
o LIMIT
. EXPLAIN
dovrebbe indicare in che modo sarebbe stata eseguita la query, che cosa ha usato le chiavi, come le tabelle sono unite, ecc La clausola LIMIT
è un po 'come un modificatore di query post ... ora che sappiamo quello che vogliamo, solo dare il em prima così tanti. Così, il campo righe contiene il numero di possibili file che esistono nella query. Da lì, OFFSET
e LIMIT
avrebbero selezionare quelli specifici che si desidera.
Sto pensando che se si eseguisse il tuo SELECT
senza EXPLAIN
, si otterrebbe il numero di record che si voleva.
Sì, il problema è che l'indice non è corretto. Voglio dire che indicizzati tutti i 3 campi e la vostra selezione di query controlla solo per uno. In MySQL indicizzazione 2 righe separatamente è diverso da indicizzare 3 righe insieme.
Prova
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