[英]How to prevent this JOIN query from doing an almost full table scan
項目中的數據集包含約440萬行
在每個表上分別對updated
和created
的索引編制索引
EXPLAIN SELECT i.id, j.id
FROM jobs j
JOIN items i ON j.items_id = i.id
WHERE j.updated > DATE_SUB(NOW(), INTERVAL 60 MINUTE)
OR j.created > DATE_SUB(NOW(), INTERVAL 60 MINUTE)
OR i.updated > DATE_SUB(NOW(), INTERVAL 60 MINUTE);
這是我得到的:
1 SIMPLE i index PRIMARY,updated_idx updated_idx 5 NULL 4168353 Using index
1 SIMPLE j ref items_id_idx,updated_idx,created_idx items_id_idx 9 my_db.i.id 1 Using where
如您所見,在使用updated_idx
,這些項目仍然接近全表掃描。
為什么會這樣,無論如何我都可以避免這種情況?
也嘗試過此方法,但性能較差:
EXPLAIN SELECT i.id, j.id
FROM jobs j
WHERE j.updated > DATE_SUB(NOW(), INTERVAL 60 MINUTE)
OR j.created > DATE_SUB(NOW(), INTERVAL 60 MINUTE)
OR j.items_id IN
(SELECT i.id FROM items i WHERE i.updated > DATE_SUB(NOW(), INTERVAL 60 MINUTE));
MySql沒有優化或在where條件中設置的條件太好。 將查詢重寫為3個單獨的選擇,並與並集相連。 這樣,每個查詢都可以利用適當的索引:
SELECT i.id, j.id
FROM jobs j
JOIN items i ON j.items_id = i.id
WHERE j.updated > DATE_SUB(NOW(), INTERVAL 60 MINUTE)
UNION DISTINCT
SELECT i.id, j.id
FROM jobs j
JOIN items i ON j.items_id = i.id
WHERE j.created > DATE_SUB(NOW(), INTERVAL 60 MINUTE)
UNION DISTINCT
SELECT i.id, j.id
FROM jobs j
JOIN items i ON j.items_id = i.id
WHERE i.updated > DATE_SUB(NOW(), INTERVAL 60 MINUTE);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.