Изглежда, че по някаква причина MySQL
избира да използва индекса SIL
на първата таблица и я използва и двете за търсене (WHERE sil_id = 4601038
) и групиране (GROUP BY cu.Id
).
Можете да му кажете да използва PK
на масата
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
и ще произведе този план за изпълнение:
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
Игнорирайте стойностите, отчетени в колона rows
; те не са правилни, защото таблиците ми са празни.
Обърнете внимание на Extra
колоната вече съдържа само Using where
но също така забележете, че присъединяването type
колона е променена от ref
(много добър) към index
(пълно сканиране на индекса, не съвсем добро).
По-добро решение е да добавите индекс към колона SIL_Id
. Знам, SIL_Id
е префикс на индекс SIL(SIL_Id, AsCatId)
и на теория друг индекс на колона SIL_Id
е напълно безполезен. Но изглежда, че решава проблема в този случай.
ALTER TABLE cat_urls
ADD INDEX (SIL_Id)
;
Сега го използвайте в заявката:
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
Планът за изпълнение на заявката изглежда много по-добре сега:
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
Недостатъкът е, че имаме допълнителен индекс, който (теоретично) е безполезен. Той заема място за съхранение и консумира цикли на процесора всеки път, когато се добавя, изтрива ред или има неговия SIL_Id
поле променено.