根据我的理解,rownum在查询后应用于整个结果集.这意味着如果我想使用rownum限制结果,它仍然会首先查询所有内容.我有一个超过十万条记录的用户表.我也正在开发一个搜索此表的站点,返回结果集.不幸的是,请求者希望我包含搜索JUST姓氏的能力.
想象一下可能会回来的"琼斯","白人","棕色"的概念.我想带回不超过200条记录,有没有更好的方法来做这个而不是使用rownum?我对rownum应用时的理解是否正确?
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.
双方ROWNUM并ROW_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).
| 归档时间: |
|
| 查看次数: |
3124 次 |
| 最近记录: |