Oracle rownum <[n]替代方案?对此事的认知?

Eri*_*rms 3 sql oracle

根据我的理解,rownum在查询后应用于整个结果集.这意味着如果我想使用rownum限制结果,它仍然会首先查询所有内容.我有一个超过十万条记录的用户表.我也正在开发一个搜索此表的站点,返回结果集.不幸的是,请求者希望我包含搜索JUST姓氏的能力.

想象一下可能会回来的"琼斯","白人","棕色"的概念.我想带回不超过200条记录,有没有更好的方法来做这个而不是使用rownum?我对rownum应用时的理解是否正确?

Qua*_*noi 8

SELECT  *
FROM    (
        SELECT  *
        FROM    mytable
        WHERE   lastname = 'Jones'
        ORDER BY
                id
        )
WHERE   rownum <= 200
Run Code Online (Sandbox Code Playgroud)

要么

SELECT  *
FROM    (
        SELECT  *, ROW_NUMBER() OVER (ORDER BY id) rn
        FROM    mytable
        WHERE   lastname = 'Jones'
        )
WHERE   rn <= 200
Run Code Online (Sandbox Code Playgroud)

后者速度较慢9i但工作方式相同10g+.

根据我的理解,rownum在查询后应用于整个结果集

号的rownum是尽快适用满足每个记录WHERE条款被取出(但他们购买后).

实际上,这里需要嵌套查询,因为ROWNUM在之前进行了求值ORDER BY.

双方ROWNUMROW_NUMBER()受到优化.如果您有索引(lastname, id),查询将使用索引并在返回第200条记录后停止(您将COUNT(STOPKEY)在计划中看到一个).

还有一个常见的警告ROWNUM和分页.这个查询:

SELECT  *
FROM    (
        SELECT  *
        FROM    mytable
        WHERE   lastname = 'Jones'
        ORDER BY
                id
        )
WHERE   rownum BETWEEN 201 AND 400
Run Code Online (Sandbox Code Playgroud)

将永远不会返回任何东西,因为ROWNUM它本身就是WHERE条件的一部分.引擎只是不能返回第一行,因为它将ROWNUM = 1不满足该WHERE子句.

要解决此问题,您必须对查询进行双重嵌套:

SELECT  *
FROM    (
        SELECT  q.*, ROWNUM AS rn
        FROM    (
                SELECT  *
                FROM    mytable
                WHERE   lastname = 'Jones'
                ORDER BY
                        id
                ) q
        )
WHERE   rn BETWEEN 201 AND 400
Run Code Online (Sandbox Code Playgroud)

这也将被优化COUNT(STOPKEY).