浏览 1581 次
锁定老帖子 主题:讨论如何优化这条sql
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-09-11
SELECT * FROM (SELECT ROWNUM ROWSEQ, SQLA.* FROM (SELECT * FROM QMYS_V_ZLCS WHERE 1 = 1 AND SPZT IN ('A', 'B', 'C', 'D') ) SQLA) WHERE ROWSEQ BETWEEN 1 AND 15 ORDER BY QMYS_ZLCS_ID desc哪位可以优化一下?谢谢! 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-09-12
首先这条SQL是不对的
这个SQL,是个典型的SQL分页语句, ORDER BY 条件应当放到最里面的子查询中 SELECT * FROM ( SELECT ROWNUM ROWSEQ, SQLA.* FROM ( SELECT * FROM QMYS_V_ZLCS WHERE 1 = 1 AND SPZT IN ('A', 'B', 'C', 'D') ORDER BY QMYS_ZLCS_ID desc ) SQLA ) WHERE ROWSEQ BETWEEN 1 AND 15 SPZT的IN条件,可以考虑写成 OR 的形式 当然,如果是ORACLE9I以上版本,ORACLE的SQL编译器会自动作如上优化 当SPZT的值取'A', 'B', 'C', 'D'的记录占总记录数的比例很小(比如说5%以下)时, 可以考虑在SPZT上加上索引,没有索引的话会造成全表扫描 而当这个比例比较大的时候,加上索引反而可能会变得更慢 可以考虑BETWEEN AND用<=和>=改写 SELECT * FROM ( SELECT ROWNUM ROWSEQ, SQLA.* FROM ( SELECT * FROM QMYS_V_ZLCS WHERE ( A.SPZT = 'A' OR A.SPZT = 'B' OR A.SPZT = 'C' OR A.SPZT = 'D' ) ORDER BY QMYS_ZLCS_ID desc ) SQLA WHERE ROWNUM <= 15 ) WHERE ROWSEQ >= 1 当然,如果是单纯的想要查询前15条记录 可以用下面的这个SQL,少一层嵌套 SELECT ROWNUM ROWSEQ, SQLA.* FROM ( SELECT * FROM QMYS_V_ZLCS WHERE ( A.SPZT = 'A' OR A.SPZT = 'B' OR A.SPZT = 'C' OR A.SPZT = 'D' ) ORDER BY QMYS_ZLCS_ID desc ) SQLA WHERE ROWNUM <= 15 另外,在ORACLE下可以用ROWNUMBER()函数改写这个SQL语句 SELECT * FROM ( SELECT ROW_NUMBER() OVER(ORDER BY QMYS_ZLCS_ID desc) AS ROW_NO , A.* FROM QMYS_V_ZLCS A WHERE ( A.SPZT = 'A' OR A.SPZT = 'B' OR A.SPZT = 'C' OR A.SPZT = 'D' ) ) X WHERE X.ROW_NO BETWEEN 1 AND 15 |
|
返回顶楼 | |