Jim*_*mmy 2 oracle paging pagination row-number rownum
当需要在网站上完成分页时...哪种方法表现更好?
分析函数 - ROW_NUMBER()
http://www.oracle.com/technetwork/issue-archive/2007/07-jan/o17asktom-093877.html
SELECT columnA,
columnB
FROM (SELECT columnA,
columnB,
row_number() over (order by columnB) rn
FROM table)
WHERE rn BETWEEN LOW_LIMIT AND OFFSET;
Run Code Online (Sandbox Code Playgroud)ROWNUM
INMHO我发现这种方法更易于人工阅读
SELECT * FROM (
SELECT rownum rn, a.*
FROM(
SELECT columnA, columnB
FROM table
ORDER BY columnB
) a
WHERE rn <= OFFSET
)
WHERE rnum >= LOW_LIMIT
Run Code Online (Sandbox Code Playgroud)
注意:我知道有RANK和DENSE_RANK分析函数,但我们假设我只需要通过确定性查询页面.
注意2:使用单独的简单查询计数(*)检索我正在考虑的记录总量
我觉得这个问题很有趣,所以我尝试了一些东西.
我有一个名为large_t的表,它包含大约1.1M行.
然后我有两个问题:
select *
from
(
select rownum rnum, a.*
from (
select owner, object_name, object_id
from large_t
order by object_id
) a
where rownum <= 30
) where rnum > 20;
Run Code Online (Sandbox Code Playgroud)
和
select *
from
(
select owner, object_name, object_id,
row_number() over (order by object_id) rnum
from large_t
) where rnum > 20 and rnum <= 30;
Run Code Online (Sandbox Code Playgroud)
如果你查看两个查询生成的计划,第一个有一个操作:
SORT ORDER BY STOPKEY
Run Code Online (Sandbox Code Playgroud)
分析查询包含一个名为的操作
WINDOW SORT PUSHED RANK
Run Code Online (Sandbox Code Playgroud)
SORT ORDER BY STOPKEY是一个更有效的排序操作,它是一个简单的ORDER BY.我不确定WINDOW SORT PUSHED RANK是如何工作的,但它似乎以类似的方式工作.
在运行两个查询后查看v $ sql_workarea,两者都只需要一个4096字节的sort_area.
相反,如果我在没有分页查询的情况下运行查询:
select owner, object_name, object_id
from large_t
order by object_id
Run Code Online (Sandbox Code Playgroud)
然后所需的排序区域是37M,证明两个查询中的排序大致相同.
通常,如果您想要有效地返回已排序查询的TOP N,您将需要排序列上的索引 - 这将阻止Oracle根本需要排序.所以,我在OBJECT_ID上创建了一个索引,然后再次解释了这两个查询.
这次第一个查询使用索引并在0.2秒内返回,而第二个查询没有使用新索引并且速度慢得多.
因此,我从这一快速分析的结论是,在使用rownum过滤或分析row_number函数的一般情况下,两者的执行大致相同.但是,当row_number没有时,rownum示例使用我在表上创建的索引自动启动.也许我可以通过一些提示来使用索引 - 这是你可以尝试的其他东西.
| 归档时间: |
|
| 查看次数: |
17468 次 |
| 最近记录: |