Type ALL si on sélectionne une colone non-indexée ?
Je suis en train d'essayer de résoudre une requête problématique, alors je l'analyse avec EXPLAIN:
Code:
1 2 3 4 5 6 7 8
|
mysql> EXPLAIN SELECT * FROM cc_he_fromto WHERE persoid=325;
+----+-------------+--------------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------+------+---------------+------+---------+------+--------+-------------+
| 1 | SIMPLE | cc_he_fromto | ALL | PRIMARY | NULL | NULL | NULL | 108421 | Using where |
+----+-------------+--------------+------+---------------+------+---------+------+--------+-------------+
1 row in set (0.01 sec) |
Le problème c'est le Type= ALL, qui fait en sorte que ma requête met un temps fou à être exécutée. La table est assez grosse, et je dois absolument éviter les FULL TABLE SCAN.
Voici ma table:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
mysql> SHOW COLUMNS FROM cc_he_fromto;
+-------------+-----------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-----------------------+------+-----+---------+-------+
| msgid | int(12) unsigned | NO | PRI | 0 | |
| fromto | enum('from','to') | NO | PRI | from | |
| persoid | varchar(12) | NO | PRI | 0 | |
| lieuid | mediumint(5) unsigned | NO | | 0 | |
| masque | tinyint(1) | NO | | 0 | |
| description | text | NO | | NULL | |
| show | tinyint(1) | NO | PRI | 1 | |
+-------------+-----------------------+------+-----+---------+-------+
7 rows in set (0.01 sec) |
Du coté de mes index, ca ressemble à ceci:
Code:
1 2 3 4 5 6 7 8 9 10 11 12
|
mysql> SHOW INDEX FROM cc_he_fromto;
+--------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+--------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| cc_he_fromto | 0 | PRIMARY | 1 | persoid | A | 30 | NULL | NULL | | BTREE | |
| cc_he_fromto | 0 | PRIMARY | 2 | show | A | 30 | NULL | NULL | | BTREE | |
| cc_he_fromto | 0 | PRIMARY | 3 | msgid | A | 185357 | NULL | NULL | | BTREE | |
| cc_he_fromto | 0 | PRIMARY | 4 | fromto | A | 185357 | NULL | NULL | | BTREE | |
| cc_he_fromto | 1 | msgid | 1 | msgid | A | 185357 | NULL | NULL | | BTREE | |
+--------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
5 rows in set (0.18 sec) |
Enfin, là ou je ne comprend plus rien, c'est que si je sélectionne des champs indexé, le type ALL change pour type INDEX:
Code:
1 2 3 4 5 6 7 8
|
mysql> EXPLAIN SELECT msgid, fromto, persoid, `show` FROM cc_he_fromto WHERE persoid=325;
+----+-------------+--------------+-------+---------------+-------+---------+------+--------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------+-------+---------------+-------+---------+------+--------+--------------------------+
| 1 | SIMPLE | cc_he_fromto | index | PRIMARY | msgid | 4 | NULL | 185361 | Using where; Using index |
+----+-------------+--------------+-------+---------------+-------+---------+------+--------+--------------------------+
1 row in set (0.00 sec) |
Mais si j'ajoute "masque", "lieuid" ou "description", je retombe à type ALL. Meme que si je met seulement un de ces 3 champs, je retombe à type ALL:
Code:
1 2 3 4 5 6 7 8
|
mysql> EXPLAIN SELECT lieuid FROM cc_he_fromto WHERE persoid=325;
+----+-------------+--------------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------+------+---------------+------+---------+------+--------+-------------+
| 1 | SIMPLE | cc_he_fromto | ALL | PRIMARY | NULL | NULL | NULL | 185322 | Using where |
+----+-------------+--------------+------+---------------+------+---------+------+--------+-------------+
1 row in set (0.00 sec) |
Quelqu'un pourrait m'éclairer un peu sur la raison de ce comportement ? Pourquoi MySQL se pré-occupe des champs à sélectionner ?
Merci !
Note:
Je suis conscient que SHOW est un mot clé réservé, et il est toujours entre `` dans mes requêtes.