Je suis en train d'essayer de résoudre une requête problématique, alors je l'analyse avec EXPLAIN:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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.