首页 > 解决方案 > Oracle - 这个查询可以优化吗?

问题描述

我想获取一组行的最后一个日期。什么更高效:Query1 或 Query2:

查询1

select *
from(
select column_date
from table1 a join table2 b on a.column1=b.column1
where id= '1234'
order by column_date desc) c
where rownum=1

查询2

select column_date
from table1 a join table2 b on a.column1=b.column1
where id= '1234'
order by column_date desc

并在后端取第一行。

或者也许有另一种方法可以在 Oracle 中占据第一行?我知道通常子选择的性能很差。这就是我试图删除子选择的原因。

我试过了,但我没有得到预期的结果:

select column_date
from table1 a join table2 b on a.column1=b.column1
where id= '1234' and rownum=1
order by column_date desc

标签: sqloracle

解决方案


首先,您无法真正优化查询。查询总是由优化器重写,并且可能会根据有多少数据、索引等给出非常不同的结果。因此,如果您的查询速度很慢,则必须查看执行计划以了解发生了什么。如果您有一个不慢的查询,您不应该优化它。

子选择本身没有任何问题。正如 Wernfriend Domscheit 所建议的,这将为您提供最小的 column_date,我假设它位于 table2 中。

SELECT MIN( b.column_date ) 
  FROM table1 a 
 INNER JOIN table2 b on a.column1 = b.column1 
 WHERE a.id= '1234'

这保证给你一个单行。如果您需要的不仅仅是日期字段,这将选择具有最短日期的行:

 SELECT a.*, b.column_date
  FROM table1 a 
 INNER JOIN table2 b on a.column1 = b.column1 
 WHERE a.id= '1234'
   AND b.column_date = ( SELECT MIN( b2.column_date ) FROM table2 b2 )

但是,如果您的 column_date 不是唯一的,则可能会返回多行。如果可能的话,您将需要数据中的某些内容来区分要选择的行。这保证给你一行:

SELECT * FROM (
     SELECT a.*, b.column_date
      FROM table1 a 
     INNER JOIN table2 b on a.column1 = b.column1 
     WHERE a.id= '1234'
       AND b.column_date = ( SELECT MIN( b2.column_date ) FROM table2 b2 )
     ORDER BY a.some_other_column 
)
WHERE ROWNUM = 1

在足够新的 Oracle 版本中,您可以使用查询FETCH FIRST 1 ROW ONLY来代替 ROWNUM。我不认为这有什么不同。


推荐阅读