我正在處理有關着陸頁的一些查詢。該頁面將爲用戶提供各種搜索選項。這些查詢將根據用戶選擇和啓動到DB2數據庫的各個部分構建。總而言之,有超過100個獨特的查詢。我正在努力降低性能,並且我有一個需要太長時間。基本結構是這樣的:SQL - 有問題的OR子句破壞查詢時間
SELECT ...
FROM
TABLE A
--A few joins and a few left joins--
WHERE A.FIELD1 IS NOT NULL
AND A.FIELD2 IN (:parameter) --No more than two values in here
AND (
A.FIELD3 IN ('ONE', 'TWO')
OR (A.FIELD3 IN ('THREE','FOUR') AND A.FIELD4 BETWEEN :x AND :y)
)
AND A.FIELD5 IN (uncorrelated subquery, potentially returns over 1k values, usually less)
FIELD2和3被選中,而其他只被過濾。 FIELD5用於連接,但這與使用子查詢進行篩選無關。問題來自(X OR Y)子句。查詢大約需要3秒鐘來執行。如果我刪除OR子句中的任一條件,它將在不到十分之一的時間內執行。奇怪的是,刪除它們都會使它回到3秒左右,這沒有多大意義,因爲它似乎並沒有增加太多數據集的大小。帶有OR子句的解釋計劃或沒有這兩個條件的解釋計劃幾乎完全相同,但它似乎並不是一個索引問題,因爲它看起來在相關表上找到了相同的索引。在這兩種情況下,最大的NLJOIN成本都很高。從OR子句中刪除一個條件(所以它只是一個AND),並且解釋計劃發生了顯着變化,雖然使用了相同的相關索引,但大大降低了成本並顯着改變了結構。
我試着解決這個問題與子查詢和工會,甚至使用兩個查詢之間的區別只有在該條款(這確實有助於這個實例一點點,但顯着減慢其他查詢),但沒有任何似乎有助於執行時間。由於查詢非常龐大,我無法真正發佈完整的詳細信息,但希望這足以讓這個想法貫穿始終。我知道OR子句有時可以將優化器放到一個循環中,所以我猜一般的建議是避免有問題的OR子句,或者將優化器推向更好的方向,這是非常值得讚賞的,即使它並不直接針對此示例。
成功!這大大減少了幾次查詢的執行時間,同時使其它的查詢大部分時間不受影響。它可能略微增加了少數幾個人的執行時間,但它在單位數百分比內(並且沒有假設它在誤差範圍內),所以它絕對是一個整體收益。謝謝先生,你是個紳士和學者! – user1017413