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.