这是我的(简化的)问题,我想这是很常见的:
create table sample (client, recordDate, amount)
我想找出最新的记录,为每个客户,与recordDate和金额。
我编写了下面的代码,它可以工作,但我想知道是否有更好的模式或Oracle调整来提高这种选择的效率。(我不被允许修改数据库的结构,所以索引等对我来说是遥不可及的,也超出了这个问题的范围)。
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万条记录,select需要2-4秒,这是可以接受的,但我很好奇是否可以改进。
谢谢
发布于 2014-05-14 22:59:14
在大多数情况下,窗口聚合函数的性能可能会更好(至少它更容易编写):
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发布于 2014-05-14 23:14:26
查询的另一个结构是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的查询)应该都有不同的查询计划,您可能会幸运地找到其中一个。不过,最好的解决方案是拥有适当的索引。
https://stackoverflow.com/questions/23658237
复制相似问题