大数据集的分页

时间:2015-07-09 19:46:45

标签: sql oracle pagination

我有一个返回大(10000多行)数据集的查询。我想按日期desc订购,并显示前40个结果。有没有办法运行这样的查询,只检索那40个结果而不先检索所有10000个?

我有这样的事情:

select rownum, date, * from table
order by date desc

这将选择所有数据并按日期对其进行排序,但是rownum不按顺序排列,因此仅选择前40个数据无效。

ROW_NUMBER() over (ORDER BY date desc) AS rowNumber

^将按顺序显示rownumber,但我不能在where子句中使用它,因为它是一个窗口函数。我可以运行这个:

select * from (select ROW_NUMBER() over (ORDER BY date desc) AS rowNumber,
 rownum, * from table
order by date desc) where rowNumber between pageStart and pageEnd

但这是选择所有10000行。我怎样才能有效地做到这一点?

3 个答案:

答案 0 :(得分:5)

SELECT *
  FROM (SELECT *
          FROM table
         ORDER BY date DESC)
 WHERE rownum <= 40

将返回date排序的前40行。如果date上有一个可用于查找这些行的索引,并假设统计信息是最新的,那么Oracle应该选择使用该索引来识别所需的40行,然后执行40行单行查找表以检索其余数据。如果你想要,你可以在内部查询中抛出一个/*+ first_rows(40) */提示,但不应该有任何影响。

有关分页查询和前N个查询的更一般性讨论,这里有一个很好的discussion from Tom Kyte和一个much longer AskTom discussion

答案 1 :(得分:2)

Oracle 12c引入了row limiting子句:

SELECT *
FROM   table
ORDER BY "date" DESC
FETCH FIRST 40 ROWS ONLY;

在早期版本中,您可以这样做:

SELECT *
FROM   ( SELECT *
         FROM   table
         ORDER BY "date" DESC )
WHERE  ROWNUM <= 40;

SELECT *
FROM   ( SELECT *,
                ROW_NUMBER() OVER ( ORDER BY "date" DESC ) AS RN
         FROM   table )
WHERE  RN <= 40;

SELECT *
FROM   TEST
WHERE  ROWID IN ( SELECT ROWID
                  FROM   ( SELECT "Date" FROM TEST ORDER BY "Date" DESC )
                  WHERE  ROWNUM <= 40 );

无论您做什么,数据库都需要查看date列中的所有值,以查找40个第一项。

答案 2 :(得分:-1)

您不需要窗口功能。参见

http://www.techonthenet.com/oracle/questions/top_records.php

找到问题的答案。