在表中选择`n`最后插入的记录 - oracle

zen*_*dar 6 sql oracle oracle10g

表具有从序列生成的代理主键.不幸的是,这个序列用于为其他一些表生成密钥(我没有设计它,我也无法改变它).

n在Oracle中选择最后插入记录的最快方法是什么,按ID按降序排列(最后插入到顶部)?

n 是一些相对较小的数字 - 页面上显示的记录数 - 可能不超过50.

表现在有30.000.000条记录,每天有10-15,000条新记录.

数据库是Oracle 10g.

编辑:
回答一条评论:这个问题的动机是查询的执行计划:

  select * from MyTable order by primarykeyfield desc
Run Code Online (Sandbox Code Playgroud)

执行计划是:

--------------------------------------------- 
| Id  | Operation          | Name        |     
---------------------------------------------  
|   0 | SELECT STATEMENT   |             |
|   1 |  SORT ORDER BY     |             |
|   2 |   TABLE ACCESS FULL| MyTable     |
---------------------------------------------  
Run Code Online (Sandbox Code Playgroud)

我很惊讶Oracle希望在排序字段上有索引时执行全表扫描和排序.

来自已接受答案的查询使用索引并避免排序.

编辑2:
Re.APC的评论:排序是让我感到惊讶的一部分.我预计Oracle会使用index来按预期顺序检索行.查询执行计划:

select * from (select * from arh_promjene order by promjena_id desc) x 
   where rownum < 50000000
Run Code Online (Sandbox Code Playgroud)

使用索引而不是全表访问和排序(通知条件rownum < 50.000.000- 这比表中的记录数量多,Oracle知道它应该从表中检索所有记录).此查询将所有行作为第一个查询返回,但具有以下执行计划:

| Id  | Operation                     | Name         | 
-------------------------------------------------------
|   0 | SELECT STATEMENT              |              | 
|*  1 |  COUNT STOPKEY                |              | 
|   2 |   VIEW                        |              | 
|   3 |    TABLE ACCESS BY INDEX ROWID| MyTable      | 
|   4 |     INDEX FULL SCAN DESCENDING| SYS_C008809  | 

Predicate Information (identified by operation id):    
---------------------------------------------------    

   1 - filter(ROWNUM<50000000)                         
Run Code Online (Sandbox Code Playgroud)

对我来说,Oracle正在为这两个基本上返回相同结果集的查询创建不同的执行计划.

编辑3: Re Amoq的评论:

Oracle不知道50M大于行数.当然,它有统计数据,但它们可能是旧的和错误的 - 并且Oracle永远不会仅仅因为统计数据错误而允许自己传递错误的结果.

你确定吗?在最多9个Oracle版本中,建议不时手动刷新统计信息.从版本10开始,Oracle会自动更新统计信 如果Oracle不将其用于查询优化,那么统计数据的用途是什么?

Don*_*nie 15

用途ROWNUM:

select
  *
from
  (
    select
      *
    from
      foo
    order by
      bork
   ) x
where
  ROWNUM <= n
Run Code Online (Sandbox Code Playgroud)

请注意,排序子查询之前rownum应用,这就是您需要两个嵌套查询的原因,否则您将获得随机行.n