论坛首页 入门技术论坛

讨论如何优化这条sql

浏览 1581 次
精华帖 (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
哪位可以优化一下?谢谢!
   发表时间: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 



0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics