使用rownum = 1和order by编写Oracle Select语句的最佳方法

时间:2017-08-24 15:47:08

标签: sql oracle query-optimization

我有一个oracle select语句,但需要1.58秒来获取我的1行,这对于这个单一查询来说是很长时间>表包含大量数据

 select g.id
   from TBL1 g 
   left join TBL2 b on g.REF1= b.REF2 
  where b.id = 286 
    and ROWNUM = 1 
  order by g.id desc 

但是当我选择所有数据而没有订购也没有限制它需要0.027 !!

实现这一目标的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

如果您使用的是Oracle 12.1,则可以使用前N个查询:

select g.id
   from TBL1 g 
   left join TBL2 b on g.REF1= b.REF2 
  where b.id = 286 
  order by g.id desc
FETCH FIRST 1 ROW ONLY

否则,您可以使用子查询获取第一行:

select * from (
  select g.id
     from TBL1 g 
     left join TBL2 b on g.REF1= b.REF2 
    where b.id = 286 
    order by g.id desc
) where ROWNUM = 1

这两种形式都允许Oracle使用top-N优化,以避免在对结果进行排序时将整个结果集保存在temp中。

要进一步优化,您需要查看表,索引和查询的解释计划。一些粗略的想法/猜测:

  • 检查TBL2.id是否有索引
  • 考虑TBL2 (id,REF2)
  • 上的索引
  • 检查TBL1.REF1是否有索引
  • 考虑TBL1 (REF1,id)
  • 上的索引

但是,在考虑上述情况之前,请确保您要优化的查询实际上是您的应用程序将使用的查询。您怀疑在查询中是否有硬编码的文字值286 - 也许这应该是绑定变量。

P.S。由于b.id上的WHERE子句,这不是外部联接,因此left关键字是多余的。