Es sieht so aus, als ob aus irgendeinem Grund MySQL wählt den Index SIL in der ersten Tabelle und verwendet sie beide für die Suche (WHERE sil_id = 4601038 ) und Gruppierung (GROUP BY cu.Id ).
Sie können es anweisen, den PK zu verwenden der Tabelle
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
und es wird dieser Ausführungsplan erstellt:
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
Ignorieren Sie die in Spalte rows gemeldeten Werte ; sie sind nicht korrekt, weil meine Tabellen leer sind.
Beachten Sie das Extra Spalte enthält jetzt nur noch Using where Beachten Sie aber auch, dass der Join type ist Spalte von ref geändert (sehr gut) zum index (vollständiger Index-Scan, nicht ganz gut).
Eine bessere Lösung besteht darin, der Spalte SIL_Id einen Index hinzuzufügen . Ich weiß, SIL_Id ist ein Präfix des Index SIL(SIL_Id, AsCatId) und theoretisch ein weiterer Index auf Spalte SIL_Id ist völlig nutzlos. Aber es scheint, dass es das Problem in diesem Fall löst.
ALTER TABLE cat_urls
ADD INDEX (SIL_Id)
;
Verwenden Sie es jetzt in der Abfrage:
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
Der Abfrageausführungsplan sieht jetzt viel besser aus:
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
Der Nachteil ist, dass wir einen zusätzlichen Index haben, der (theoretisch) nutzlos ist. Es belegt Speicherplatz und verbraucht jedes Mal Prozessorzyklen, wenn eine Zeile hinzugefügt oder gelöscht wird oder ihre SIL_Id hat Feld geändert.