It seems that for some reason, MySQL chooses to use the SIL index in the first table and uses it both for searching ( WHERE sil_id = 4601038 ) and for grouping ( GROUP BY cu.Id ).
You can say to use PK tables
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
and he will execute this execution plan:
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 the values specified in the rows column ; they are wrong because my tables are empty.
Note that the Extra column now only contains Using where , but also notices that the type join column has changed from ref (very good) to index (full index scan, not very good).
The best solution is to add an index to the SIL_Id column. I know SIL_Id is the SIL(SIL_Id, AsCatId) index prefix SIL(SIL_Id, AsCatId) , and theoretically another index in the SIL_Id column SIL_Id completely useless. But it seems to solve the problem in this case.
ALTER TABLE cat_urls ADD INDEX (SIL_Id) ;
Now use it in the query:
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
Now the query execution plan looks much better:
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
The downside is that we have an additional index that is (theoretically) useless. It takes up storage space and consumes processor cycles each time a row is added, deleted, or the SIL_Id field is SIL_Id .