Wygląda na to, że z jakiegoś powodu MySQL
wybiera użycie indeksu SIL
w pierwszej tabeli i używa ich do wyszukiwania (WHERE sil_id = 4601038
) i grupowanie (GROUP BY cu.Id
).
Możesz powiedzieć mu, aby używał PK
stołu
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
i przedstawi ten plan wykonania:
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
Ignoruj wartości zgłoszone w kolumnie rows
; nie są poprawne, ponieważ moje tabele są puste.
Zwróć uwagę na Extra
kolumna zawiera teraz tylko Using where
ale zauważ też, że złącze type
kolumna zmieniona z ref
(bardzo dobrze) do index
(pełny skan indeksu, niezbyt dobry).
Lepszym rozwiązaniem jest dodanie indeksu w kolumnie SIL_Id
. Wiem, SIL_Id
jest prefiksem indeksu SIL(SIL_Id, AsCatId)
i teoretycznie kolejny indeks w kolumnie SIL_Id
jest całkowicie bezużyteczny. Ale wydaje się, że to rozwiązuje problem w tej sprawie.
ALTER TABLE cat_urls
ADD INDEX (SIL_Id)
;
Teraz użyj go w zapytaniu:
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
Plan wykonania zapytania wygląda teraz znacznie lepiej:
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
Wadą jest to, że mamy dodatkowy indeks, który jest (teoretycznie) bezużyteczny. Zajmuje miejsce w pamięci i zużywa cykle procesora za każdym razem, gdy wiersz jest dodawany, usuwany lub ma swój SIL_Id
pole zmienione.