Tampaknya, untuk beberapa alasan, MySQL memilih untuk menggunakan indeks SIL pada tabel pertama dan menggunakan keduanya untuk pencarian (WHERE sil_id = 4601038 ) dan pengelompokan (GROUP BY cu.Id ).
Anda dapat memberitahunya untuk menggunakan PK dari tabel
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
dan itu akan menghasilkan rencana eksekusi ini:
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
Abaikan nilai yang dilaporkan di kolom rows ; mereka tidak benar karena tabel saya kosong.
Perhatikan Extra kolom sekarang hanya berisi Using where tetapi juga perhatikan bahwa gabungan type kolom diubah dari ref (sangat bagus) untuk index (pemindaian indeks penuh, tidak cukup baik).
Solusi yang lebih baik adalah menambahkan indeks pada kolom SIL_Id . Saya tahu, SIL_Id adalah awalan dari indeks SIL(SIL_Id, AsCatId) dan secara teori indeks lain pada kolom SIL_Id sama sekali tidak berguna. Tapi sepertinya itu menyelesaikan masalah dalam kasus ini.
ALTER TABLE cat_urls
ADD INDEX (SIL_Id)
;
Sekarang gunakan dalam kueri:
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
Rencana eksekusi kueri terlihat jauh lebih baik sekarang:
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
Kekurangannya adalah kami memiliki indeks tambahan yang (secara teoritis) tidak berguna. Ini menempati ruang penyimpanan dan menghabiskan siklus prosesor setiap kali baris ditambahkan, dihapus, atau SIL_Id-nya bidang diubah.