MySQL - 如何優化大表查詢中的多個 OR 條件
我有一個具有以下結構的表:
Configuration ( id: binary(16) Primary key, htId: binary(16), raId: binary(16), date, amount );
我已經創建了這些索引:
idx_ht (htId) BTREE, idx_ra (raId) BTREE, idx_date (date) BTREE, idx_ht_ra_date (raId, htId, date) BTREE。
該表有近 1.5 億條記錄。
這是我要優化的具有多個 htId-raId 對的慢查詢。
Select htId, raId, SUM (amount) as totalAmount From Configuration r Where ((r.htId = htId_1 AND r.raId = raId_2) OR (r.htId = htId_3 AND r.raId = raId_4) ... ~1000 pairs more (r.htId = htId_X AND r.raId = raId_X)) AND date Between fromDate AND toDate Group by r.htId, r.raId Having Count(1) = DATE_DIFF(fromDate, toDate) Order by totalAmount ASC LIMIT 0,100
有什麼辦法可以優化上面的查詢嗎?當查詢有多個這樣的 OR 時,索引似乎對我的查詢沒有任何影響。查詢需要很多時間。任何幫助將不勝感激。BR。
OR
很難優化,尤其是其中的 1000 個。看看你是否可以通過一個表中的值,然後
JOIN
到那個表。然後提供
EXPLAIN SELECT ...
.
(and ) 子句中的許多
OR
ed 謂詞通常難以優化。它們通常會強制進行索引掃描,或者更糟糕的全表掃描。WHERE``JOIN … ON
一個常見的優化是將所有
OR
s 重構為單獨SELECT
的 s,然後將UNION
它們重構,如下所示:SELECT Things FROM Tables WHERE Condition1 OR Condition2 … … OR ConditionN
變成
SELECT Things FROM Tables WHERE Condition1 UNION SELECT Things FROM Tables WHERE Condition2 … … UNION SELECT Things FROM Tables WHERE ConditionN
如果返回大量行,這可能會非常低效,因為這
UNION
意味著某種結果集。如果您知道每個過濾子句都將始終相互返回不同的行,則可以通過使用UNION ALL
. 對於您的約 1,000 個子句,它實際上可能並不實用。當然,可能會有一個重新排列少得多的解決方案。例如,我希望索引 on
date
會有很大幫助。也許查詢計劃器錯誤地掃描idx_ht_ra_date
而不是認為這將比date
首先過濾更有效,因為索引包含所有過濾的列。date
可能是第一個(date, raId, htId
)的複合索引$$ † $$通過在那裡給它一個更好的選擇會有所幫助。事實上,我可能也傾向於amount
包括$$ † $$所以它不需要查找任何其他內容,因為您過濾和選擇的所有內容都將包含在索引中。為了幫助更多的人,需要查看目前實際發生的情況(編輯問題以包括
EXPLAIN
輸出和其他人已經提到的其他詳細資訊)以及您希望每次返回多少行。$$ † $$如果您使用的是 MS SQL Server 的 postgres,我建議您使用
INCLUDE
支持來添加額外的欄位,但 mySql 不支持