在SQL語句中用了OR之后, 其實很不容易控制, 第一次是想讓一個帶兩個OR的用UNION去執行, 結果用了USE_CONCAT后變成了4個UNION了, 居然沒有辦法讓他按我想象的第一個OR進行UNION. 第二次是在索引上, OR條件導致了不能在索引上進行條件過濾. 現在遇到了第三次, 是同事發現的, 怕自已記不住, 就沒有征得他的同意, 在這兒共享出來了.
有下面兩個表, TYPE_ID列上值的重復性很高.
CREATE TABLE T_SMALL (TYPE_ID, ID, ...);
CREATE TABLE T_MIDDLE (TYPE_ID, ID1, ID2, ...);
運行下面的SQL時, 總是很慢, 我們已經指定用HASH JOIN, 并也指定了T_SMALL是驅動表, 百思不得其解.
SELECT .....
FROM T_SMALL S, T_MIDDLE M
WHERE S.TYPE_ID = M.TYPE_ID
AND (S.ID = M.ID1 OR S.ID = M.ID2)
第一百零一思時, 發現了原因所在, 因為OR的問題, Oracle在做HASH JOIN時只依據了TYPE_ID這個效率不高的列, 這時的PLAN中肯定出現了FILTER這樣的步驟. 后來將這個語句手工改成UNION方式, 就從2個小時變成了15分鐘.
SELECT .....
FROM T_SMALL S, T_MIDDLE M
WHERE S.TYPE_ID = M.TYPE_ID
AND S.ID = M.ID1
UNION ALL
SELECT .....
FROM T_SMALL S, T_MIDDLE M
WHERE S.TYPE_ID = M.TYPE_ID
AND S.ID = M.ID2 AND M.ID1 <> M.ID2
SQL語句的調優, 其實很需要功夫, 也是一門很深的學問, 如此簡單的SQL, 也有很深刻的知識.