爪哇一角

共同探讨STRUTS#HIBERNATE#SPRING#EJB等技术
posts - 3, comments - 6, trackbacks - 0, articles - 99
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

sql语句中or用法的优化

Posted on 2011-03-21 20:11 非洲小白脸 阅读(3290) 评论(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, 也有很深刻的知识.


只有注册用户登录后才能发表评论。


网站导航: