How*_*wie 27 oracle pagination
问题:我需要写存储过程(S)将返回行的单个页面的结果集和总的行数.
解决方案A:我创建了两个存储过程,一个返回单个页面的结果集,另一个返回标量 - 总行数.解释计划说第一个sproc的成本为9,第二个的成本为3.
SELECT *
FROM ( SELECT ROW_NUMBER() OVER ( ORDER BY D.ID DESC ) AS RowNum, ...
) AS PageResult
WHERE RowNum >= @from
AND RowNum < @to
ORDER BY RowNum
SELECT COUNT(*)
FROM ...
Run Code Online (Sandbox Code Playgroud)
解决方案B:我将所有内容都放在一个sproc中,方法是在结果集中的每一行添加相同的TotalRows
数字.这个解决方案感觉很乱,但成本只有9,只有一个sproc,所以我倾向于使用这个解决方案.
SELECT *
FROM ( SELECT ROW_NUMBER() OVER ( ORDER BY D.ID DESC ) RowNum, COUNT(*) OVER () TotalRows,
WHERE RowNum >= from
AND RowNum < to
ORDER BY RowNum;
Run Code Online (Sandbox Code Playgroud)
Oracle中的分页是否有最佳实践?在实践中最常使用哪种上述解决方案?他们中的任何一个被认为是完全错误的?请注意,我的数据库将保持相对较小(小于10GB).
我正在使用Oracle 11g和最新的ODP.NET与VS2010 SP1和Entity Framework 4.4.我需要最终的解决方案才能在EF 4.4中运行.我相信一般来说可能有更好的分页方法,但是我需要他们使用EF.
Vin*_*rat 28
如果您已经在使用analytics(ROW_NUMBER() OVER ...
),那么在同一分区上添加另一个分析函数将为查询添加可忽略的成本.
另一方面,还有许多其他方式可以进行分页,其中一种方法是使用rownum
:
SELECT *
FROM (SELECT A.*, rownum rn
FROM (SELECT *
FROM your_table
ORDER BY col) A
WHERE rownum <= :Y)
WHERE rn >= :X
Run Code Online (Sandbox Code Playgroud)
如果您在订购列上有适当的索引,那么此方法将更加出色.在这种情况下,使用两个查询可能更有效(一个用于总行数,一个用于结果).
这两种方法都是合适的,但一般情况下,如果您想要行数和分页集,那么使用分析更有效,因为您只查询行一次.
这可能会有所帮助:
SELECT * FROM
( SELECT deptno, ename, sal, ROW_NUMBER() OVER (ORDER BY ename) Row_Num FROM emp)
WHERE Row_Num BETWEEN 5 and 10;
Run Code Online (Sandbox Code Playgroud)
在 Oracle 12C 中,您可以使用限制LIMIT
和OFFSET
进行分页。
示例 - 假设您有一个表tab
,需要使用分页根据DATE
数据类型列dt
按降序从该表中获取数据。
page_size:=5
select * from tab
order by dt desc
OFFSET nvl(page_no-1,1)*page_size ROWS FETCH NEXT page_size ROWS ONLY;
Run Code Online (Sandbox Code Playgroud)
解释:
page_no=1 page_size=5
OFFSET 0 ROWS FETCH NEXT 5 ROWS ONLY
- 仅获取第一 5 行
page_no=2 page_size=5
OFFSET 5 ROWS FETCH NEXT 5 ROWS ONLY
- 获取接下来的 5 行
等等。
参考页面 -
https://oracle-base.com/articles/12c/row-limiting-clause-for-top-n-queries-12cr1#paging
归档时间: |
|
查看次数: |
48700 次 |
最近记录: |