Het lijkt erop dat, om de een of andere reden, MySQL
kiest ervoor om de index SIL
. te gebruiken op de eerste tabel en het gebruikt het beide voor opzoeken (WHERE sil_id = 4601038
) en groeperen (GROUP BY cu.Id
).
Je kunt hem vertellen dat hij de PK
. moet gebruiken van de tafel
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
en het zal dit uitvoeringsplan produceren:
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
Negeer de waarden gerapporteerd in kolom rows
; ze zijn niet correct omdat mijn tabellen leeg zijn.
Let op de Extra
kolom bevat nu alleen Using where
maar merk ook op dat de join type
kolom gewijzigd van ref
(zeer goed) naar index
(volledige indexscan, niet helemaal goed).
Een betere oplossing is om een index toe te voegen aan kolom SIL_Id
. Ik weet het, SIL_Id
is een voorvoegsel van index SIL(SIL_Id, AsCatId)
en in theorie een andere index op kolom SIL_Id
is volkomen nutteloos. Maar het lijkt erop dat dit het probleem in deze zaak oplost.
ALTER TABLE cat_urls
ADD INDEX (SIL_Id)
;
Gebruik het nu in de 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
Het uitvoeringsplan voor de query ziet er nu veel beter uit:
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
Het nadeel is dat we een extra index hebben die (theoretisch) nutteloos is. Het neemt opslagruimte in beslag en het verbruikt processorcycli telkens wanneer een rij wordt toegevoegd, verwijderd of zijn SIL_Id
heeft veld gewijzigd.