Vypadá to, že z nějakého důvodu MySQL
zvolí použití indexu SIL
na první tabulce a používá ji jak pro vyhledávání (WHERE sil_id = 4601038
) a seskupení (GROUP BY cu.Id
).
Můžete mu říct, aby použil PK
tabulky
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
a vytvoří tento plán provádění:
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
Ignorujte hodnoty uvedené ve sloupci rows
; nejsou správné, protože mé tabulky jsou prázdné.
Všimněte si Extra
sloupec nyní obsahuje pouze Using where
ale také si všimněte, že spojení type
sloupec změněn z ref
(velmi dobře) index
(úplné skenování indexu, ne úplně dobré).
Lepším řešením je přidat index do sloupce SIL_Id
. Já vím, SIL_Id
je prefix indexu SIL(SIL_Id, AsCatId)
a teoreticky další index ve sloupci SIL_Id
je úplně k ničemu. Zdá se však, že problém v tomto případě řeší.
ALTER TABLE cat_urls
ADD INDEX (SIL_Id)
;
Nyní jej použijte v dotazu:
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
Plán provádění dotazu nyní vypadá mnohem lépe:
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
Nevýhodou je, že máme další index, který je (teoreticky) k ničemu. Zabírá úložný prostor a spotřebovává cykly procesoru pokaždé, když je řádek přidán, odstraněn nebo má své SIL_Id
pole upraveno.