Il semble que, pour une raison quelconque, MySQL
choisit d'utiliser l'indice SIL
sur la première table et il l'utilise à la fois pour la recherche (WHERE sil_id = 4601038
) et regroupement (GROUP BY cu.Id
).
Vous pouvez lui dire d'utiliser le PK
du tableau
SELECT cu.Href, COUNT(p.CatUrlId) FROM cat_urls cu
USE INDEX FOR JOIN (PRIMARY)
JOIN products p ON p.CatUrlId=cu.Id
WHERE sil_id=4601038
GROUP by cu.Id
et il produira ce plan d'exécution :
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
---+-------------+-------+-------+---------------+---------+---------+------------------+------+-------------
1 | SIMPLE | cu | index | PRIMARY | PRIMARY | 4 | NULL | 1 | Using where
1 | SIMPLE | p | ref | CatUrl | CatUrl | 4 | cbs-test-1.cu.Id | 1 | Using index
Ignorer les valeurs rapportées dans la colonne rows
; ils ne sont pas corrects car mes tables sont vides.
Remarquez le Extra
la colonne contient maintenant uniquement Using where
mais notez également que la jointure type
colonne modifiée de ref
(très bien) pour index
(balayage complet de l'index, pas tout à fait bon).
Une meilleure solution consiste à ajouter un index sur la colonne SIL_Id
. Je sais, SIL_Id
est un préfixe d'index SIL(SIL_Id, AsCatId)
et en théorie un autre index sur la colonne SIL_Id
est complètement inutile. Mais il semble que cela résout le problème dans cette affaire.
ALTER TABLE cat_urls
ADD INDEX (SIL_Id)
;
Utilisez-le maintenant dans la requête :
SELECT cu.Href, COUNT(p.CatUrlId) FROM cat_urls cu
USE INDEX FOR JOIN (SIL_Id)
JOIN products p ON p.CatUrlId=cu.Id
WHERE sil_id=4601038
GROUP by cu.Id
Le plan d'exécution de la requête est bien meilleur maintenant :
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
---+-------------+-------+------+---------------+--------+---------+------------------+------+-------------
1 | SIMPLE | cu | ref | SIL_Id | SIL_Id | 4 | const | 1 | Using where
1 | SIMPLE | p | ref | CatUrl | CatUrl | 4 | cbs-test-1.cu.Id | 1 | Using index
L'inconvénient est que nous avons un index supplémentaire qui est (théoriquement) inutile. Il occupe de l'espace de stockage et consomme des cycles processeur chaque fois qu'une ligne est ajoutée, supprimée ou a son SIL_Id
champ modifié.