Tengo una gran tabla de la que debo seleccionar grandes cantidades de filas.Índice compuesto MySQL no utilizado
Los tabla almacena registros detallados de llamadas (CDR). Ejemplo:
+-------------+--------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------------------+----------------+
| id | int(45) | NO | PRI | NULL | auto_increment |
| calldate | datetime | NO | MUL | 0000-00-00 00:00:00 | |
| accountcode | varchar(100) | NO | | | |
| other... | varchar(45) | NO | | | |
Desde mis consultas buscar un cliente llamadas en ciertas fechas, me indexado calldate y accountcode juntos en un índice agrupado así:
CREATE TABLE `cdr` (
`id` int(45) NOT NULL AUTO_INCREMENT,
`calldate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`accountcode` varchar(100) NOT NULL DEFAULT '',
other fields...
PRIMARY KEY (`id`),
KEY `date_acc` (`calldate`,`accountcode`) USING BTREE
) ENGINE=MyISAM DEFAULT CHARSET=latin1
Sin embargo, al ejecutar la siguiente consulta, el EXPLAIN resultado muestra que sólo la parte de fecha y hora de la clave se está utilizando:
consulta:
SELECT *
FROM cdr
WHERE calldate > '2010-12-01'
AND accountcode = 'xxxxxx';
EXPLAIN resultado:
+----+-------------+-------+-------+---------------+----------+---------+------+---------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+-------+---------------+----------+---------+------+---------+----------+-------------+
| 1 | SIMPLE | cdr | range | date_acc | date_acc | 8 | NULL | 3312740 | 100.00 | Using where |
+----+-------------+-------+-------+---------------+----------+---------+------+---------+----------+-------------+
Parece solamente los primeros 8 bytes (la parte de fecha de la clave) se está utilizando. Sin embargo, la cláusula WHERE hace referencia explícitamente a ambas partes de la clave con un AND, por lo que, en teoría, debe utilizarse la clave completa.
¿Debo crear índices separados para calldate y accountcode y dejar que el optimizador de consultas a fusionar? ¿Por qué no se usa el índice completo?
¡Gracias por la ayuda!
Parece que filtró el 100% de todas las filas con esa consulta. ¿No es ese el valor de la columna filtrada? ¿Puedes dar un ejemplo que no tenga ese filtrado? Estoy de acuerdo con una de las respuestas a continuación, primero debe tener el filtro, luego el género. index accountcode, calldate. Deberías obtener un resultado mucho mejor. – TheJacobTaylor