MySQL índice de columnas múltiples que no trabaja (como se esperaba)?
-
10-10-2019 - |
Pregunta
Tengo una tabla como la siguiente
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
ya que tengo un índice de visibilidad, NUM_SUBSCRIBERS y NUM_ITEMS, espero que sólo las primeras 15 filas sólo tienen que ser mirado, en cambio, dice EXPLICAR 55856 filas. ¿Alguna idea? Gracias
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
Solución
Su índice de campo 3 se ve bien y la EXPLAIN
es prometedor.
A pesar de que dice "55856 filas", que es sólo un estimación proporcionada por EXPLAIN
.
Desde key_len =1
, usted sabe que está usando el primer byte de su índice compuesto como una igualdad / referencia.
Dado que no hay filesort mencionado en su campo Extra
, se sabe que el ORDER BY
/ clasificación es siendo manejado por el índice.
Si marca las estadísticas de su sesión handler_%
, tendrá una mejor idea de cuántas filas son en realidad se está leyendo.
Pensamientos secundarios:
Desde que sabe que en última instancia va a golpe de disco para recuperar sus filas, si el 99% de sus datos tiene visibility=2
(especulando), que había más probable es obtener como igualmente bueno / resultados rápidos con un índice compuesto sólo en num_subscribers
y num_items
. O posiblemente como bueno / rápida si tiene un único índice en num_subscribers
, dependiendo de su cardinalidad / singularidad.
Otros consejos
No creo que se ve en la cláusula EXPLAIN
OFFSET
o LIMIT
. EXPLAIN
se supone que indica cómo se ejecuta la consulta, qué claves se utiliza, cómo se unen las tablas, etc. La cláusula LIMIT
es algo así como un modificador posterior consulta ... ahora que sabemos lo que queremos, sólo dan la em primero para muchos. Por lo tanto, el campo de filas contiene el número de filas posibles que existen en la consulta. A partir de ahí, OFFSET
y LIMIT
seleccionarían las específicas que desee.
Estoy pensando que si se ejecutara su SELECT
sin EXPLAIN
, se obtendría el número de registros que quería.
Sí, el problema es que su índice no es correcta. Me refiero a que indexan los 3 campos y su consulta de selección sólo comprueba por uno. En MySQL indexación 2 filas por separado es diferente de la indexación de 3 filas juntos.
Trate
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