Parece que, por algum motivo,
MySQL
escolhe usar o índice SIL
na primeira tabela e usa tanto para pesquisa (WHERE sil_id = 4601038
) e agrupamento (GROUP BY cu.Id
). Você pode dizer para usar o
PK
da mesa 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
e produzirá este plano de execução:
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
Ignore os valores informados na coluna
rows
; eles não estão corretos porque minhas tabelas estão vazias. Observe o
Extra
coluna agora contém apenas Using where
mas também observe que a junção type
coluna alterada de ref
(muito bom) para index
(varredura completa do índice, não muito boa). Uma solução melhor é adicionar um índice na coluna
SIL_Id
. Eu sei, SIL_Id
é um prefixo do índice SIL(SIL_Id, AsCatId)
e, em teoria, outro índice na coluna SIL_Id
é completamente inútil. Mas parece que resolve o problema neste caso. ALTER TABLE cat_urls
ADD INDEX (SIL_Id)
;
Agora use-o na consulta:
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
O plano de execução da consulta parece muito melhor agora:
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
A desvantagem é que temos um índice extra que é (teoricamente) inútil. Ocupa espaço de armazenamento e consome ciclos do processador toda vez que uma linha é adicionada, excluída ou tem seu
SIL_Id
campo modificado.