Ho una tabella grande da cui devo selezionare grandi quantità di righe.Indice composto MySQL non utilizzato
La tabella memorizza i record dei dettagli delle chiamate (CDR). Esempio:
+-------------+--------------+------+-----+---------------------+----------------+
| 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 | | | |
Poiché le mie domande cercano una clientela chiamate in determinate date, ho indicizzati calldate e accountcode insieme in un indice cluster in questo modo:
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
Tuttavia, quando si esegue la seguente query, il SPIEGARE risultato mostra che solo la parte datetime della chiave viene utilizzato:
Query:
SELECT *
FROM cdr
WHERE calldate > '2010-12-01'
AND accountcode = 'xxxxxx';
SPIEGARE risultato:
+----+-------------+-------+-------+---------------+----------+---------+------+---------+----------+-------------+
| 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 |
+----+-------------+-------+-------+---------------+----------+---------+------+---------+----------+-------------+
Sembra solo i primi 8 byte (la porzione data della chiave) viene utilizzato. Tuttavia la clausola WHERE fa esplicitamente riferimento a entrambe le parti della chiave con un AND, quindi in teoria dovrebbe essere usata la chiave completa.
Devo creare indici separati per calldate e accountcode e consentire a Query Optimizer di unirli? Perché l'indice completo non viene utilizzato?
Grazie per l'aiuto!
Sembra che abbia filtrato il 100% di tutte le righe con quella query. Non è questo il valore della colonna filtrata? Puoi fornire un esempio che non ha quel filtro? Sono d'accordo con una delle risposte qui sotto, dovresti prima avere il filtro, poi l'ordinamento. indice, codice dell'account. Dovresti ottenere un risultato molto migliore. – TheJacobTaylor