表具有从序列生成的替代主键。不幸的是,这个序列用于生成一些其他表的键(我没有设计它,我不能改变它)。在表中选择`n`最后插入记录 - oracle
什么是最快的方式来选择最后n
插入的记录在Oracle中,按ID降序排列(最后插入顶部)?
n
是一些比较小的数 - 要在页面上显示的记录数 - 可能不大于50
表现拥有30.000.000记录10-15数以千计的新记录每天。
数据库是Oracle 10g。
编辑:
在回答一个评论:这个问题与执行计划的动机查询:
select * from MyTable order by primarykeyfield desc
执行计划是:
我感到惊讶的是Oracle希望在排序字段上有索引时执行全表扫描和排序。
从接受的答案查询使用索引,并避免排序。
编辑2:
Re。 APC的评论:排序是让我感到惊讶的一部分。我预计Oracle会使用索引按预期顺序检索行。查询执行计划:
select * from (select * from arh_promjene order by promjena_id desc) x
where rownum < 50000000
使用索引来代替全表访问和排序(通知条件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)
这是不寻常的,我认为甲骨文正在为这两个查询,基本上返回相同的结果集不同的执行计划。
编辑3: 重新Amoq的评论:
Oracle不知道50M比行数更大 。当然, 它有统计数据,但它们可能是 旧的和错误的 - 并且Oracle从不会 允许自己发送错误的 结果,只是因为统计信息是 错误。
确定吗?在最多9个Oracle版本中,建议不时手动刷新统计数据。由于版本10 Oracle自动更新统计信息。如果Oracle不将它用于查询优化,那么统计数据的用途是什么?
为什么不幸的是,序列也用于其他表?查询检索最后n个插入的记录并不重要,因为一个序列永远不会被Oracle无条件地取消。所以你不能在max-n和max之间做一个简单的id。 – tuinstoel 2009-12-01 19:00:06
您的查询为* all *行选择* all *列。为什么你对Oracle进行全面的表扫描感到惊讶?否则它会如何获得数据以满足该查询? – APC 2009-12-02 11:11:31
Oracle不知道* 50M是否大于行数。当然,它有统计数据,但它们可能是老的和错误的 - 并且Oracle只会因为统计数据错误而不会允许自己提供不正确的结果。 – 2009-12-02 12:19:25