找到最大和相关字段

时间:2014-05-14 14:55:37

标签: sql oracle oracle11g

这是我的(简化)问题,我猜很常见:
create table sample (client, recordDate, amount)

我想找出每个客户的最新录音,包括recordDate和amount 我制作了以下代码,但是我想知道是否有更好的模式或Oracle调整来提高这种SELECT的效率。 (我不允许修改数据库的结构,所以索引等对我来说是遥不可及的,并且超出了问题的范围)。

select client, recordDate, Amount 
from sample s
inner join (select client, max(recordDate) lastDate
            from sample 
            group by client) t on s.id = t.id and s.recordDate = t.lastDate

该表有50万条记录,选择需要2-4秒,这是可以接受的,但我很想知道是否可以改进。

由于

2 个答案:

答案 0 :(得分:2)

在大多数情况下,窗口聚合函数可能表现更好(至少写起来更容易):

select client, recordDate, Amount 
from 
  (
   select client, recordDate, Amount,
      rank() over (partition by client order by recordDate desc) as rn 
   from sample s
  ) dt
where rn = 1

答案 1 :(得分:1)

查询的另一个结构是not exists。在某些情况下,这可以更快地执行:

select client, recordDate, Amount 
from sample s
where not exists (select 1
                  from sample s2
                  where s2.client = s.client and
                        s2.recordDate > s.recordDate
                 );

这将充分利用sample(client, recordDate)上的索引(如果有的话)。

另外,要尝试的是keep

select client, max(recordDate),
       max(Amount) keep (dense_rank first order by recordDate desc)
from sample s
group by client;

此版本假设每个客户端只有一个最大记录日期(您的原始查询不做出此假设)。

这些查询(以及dnoeth的查询)应该都有不同的查询计划,您可能会对其中一个查询计划很幸运。但是,最好的解决方案是拥有适当的索引。