爪哇一角

          共同探討STRUTS#HIBERNATE#SPRING#EJB等技術
          posts - 3, comments - 6, trackbacks - 0, articles - 99
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          sql語句中or用法的優化

          Posted on 2011-03-21 20:11 非洲小白臉 閱讀(3339) 評論(0)  編輯  收藏 所屬分類: oracle
          在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, 也有很深刻的知識.

          主站蜘蛛池模板: 张家川| 峨山| 浪卡子县| 永川市| 莎车县| 长乐市| 菏泽市| 延吉市| 肇州县| 大荔县| 云安县| 乌审旗| 克拉玛依市| 陆河县| 苍南县| 阜康市| 长治市| 昌乐县| 积石山| 额敏县| 天长市| 罗山县| 恭城| 秦安县| 庆阳市| 小金县| 海丰县| 葫芦岛市| 吉木乃县| 临城县| 石楼县| 马山县| 栾城县| 北碚区| 五华县| 乐业县| 榕江县| 北宁市| 合川市| 焉耆| 巴东县|