要在Oracle中查询top-n行,通常使用ROWNUM。 所以下面的查询似乎确定(获取最新的5个金):Oracle ROWNUM性能
select a.paydate, a.amount
from (
select t.paydate, t.amount
from payments t
where t.some_id = id
order by t.paydate desc
) a
where rownum <= 5;
但对于非常大的表,它是低效的 - 对我来说,运行约10分钟。 所以,我想其他的查询,我结束了这一次它运行了不到一秒钟:
select *
from (
select a.*, rownum
from (select t.paydate, t.amount
from payments t
where t.some_id = id
order by t.paydate desc) a
)
where rownum <= 5;
要了解发生了什么事,我看着每个查询执行计划。对于第一个查询:
SELECT STATEMENT, GOAL = ALL_ROWS 7 5 175
COUNT STOPKEY
VIEW 7 5 175
TABLE ACCESS BY INDEX ROWID 7 316576866 6331537320
INDEX FULL SCAN DESCENDING 4 6
而对于第二:
SELECT STATEMENT, GOAL = ALL_ROWS 86 5 175
COUNT STOPKEY
VIEW 86 81 2835
COUNT
VIEW 86 81 1782
SORT ORDER BY 86 81 1620
TABLE ACCESS BY INDEX ROWID 85 81 1620
INDEX RANGE SCAN 4 81
显然,索引全扫描DESCENDING,使低效的大表第一个查询。但我无法通过查看它们来区分两个查询的逻辑。 任何人都可以解释两种人类语言查询之间的逻辑差异吗?
在此先感谢!
id是绑定变量,否(应该是:id?)如果是这样,使用了什么值(相同?) – tbone 2012-02-03 12:30:05
我不认为你在第二个版本中用于过滤器的'rownum'是保证和第一个一样;认为你需要别名你的第二个查询并引用它,或者在查询中添加'order by rownum'来反对'a'?我怀疑这会影响速度。 – 2012-02-03 13:12:22