Sql 查找最大值和相关字段
这是我的(简化的)问题,我想这是很常见的:Sql 查找最大值和相关字段,sql,oracle,oracle11g,Sql,Oracle,Oracle11g,这是我的(简化的)问题,我想这是很常见的: 创建表格样本(客户、记录日期、金额) 我想找出每个客户的最新记录,包括记录日期和金额。 我编写了下面的代码,这很有效,但我想知道是否有更好的模式或Oracle调整来提高此类选择的效率。(我不允许修改数据库的结构,因此索引等对我来说是无法触及的,并且超出了问题的范围) 该表有50万条记录,select需要2-4秒,这是可以接受的,但我很好奇这是否可以改进 多亏了在大多数情况下,窗口聚合函数的性能可能会更好(至少编写起来更容易): 在大多数情况下,窗口聚合
创建表格样本(客户、记录日期、金额)
我想找出每个客户的最新记录,包括记录日期和金额。我编写了下面的代码,这很有效,但我想知道是否有更好的模式或Oracle调整来提高此类选择的效率。(我不允许修改数据库的结构,因此索引等对我来说是无法触及的,并且超出了问题的范围) 该表有50万条记录,select需要2-4秒,这是可以接受的,但我很好奇这是否可以改进
多亏了在大多数情况下,窗口聚合函数的性能可能会更好(至少编写起来更容易):
在大多数情况下,窗口聚合函数的性能可能更好(至少编写起来更容易):
在大多数情况下,窗口聚合函数的性能可能更好(至少编写起来更容易):
在大多数情况下,窗口聚合函数的性能可能更好(至少编写起来更容易):
查询的另一个结构是
不存在
。在某些情况下,这可以执行得更快:
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
);
这将很好地利用样本(客户机,记录日期)
上的索引(如果有的话)
另外,另一件事是保持
select client, max(recordDate),
max(Amount) keep (dense_rank first order by recordDate desc)
from sample s
group by client;
此版本假设每个客户机只有一个最大记录日期(您的原始查询不作此假设)
这些查询(加上dnoeth的查询)都应该有不同的查询计划,您可能会幸运地得到其中一个。不过,最好的解决方案是有适当的索引。查询的另一个结构是
不存在。在某些情况下,这可以执行得更快:
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
);
这将很好地利用样本(客户机,记录日期)
上的索引(如果有的话)
另外,另一件事是保持
select client, max(recordDate),
max(Amount) keep (dense_rank first order by recordDate desc)
from sample s
group by client;
此版本假设每个客户机只有一个最大记录日期(您的原始查询不作此假设)
这些查询(加上dnoeth的查询)都应该有不同的查询计划,您可能会幸运地得到其中一个。不过,最好的解决方案是有适当的索引。查询的另一个结构是不存在。在某些情况下,这可以执行得更快:
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
);
这将很好地利用样本(客户机,记录日期)
上的索引(如果有的话)
另外,另一件事是保持
select client, max(recordDate),
max(Amount) keep (dense_rank first order by recordDate desc)
from sample s
group by client;
此版本假设每个客户机只有一个最大记录日期(您的原始查询不作此假设)
这些查询(加上dnoeth的查询)都应该有不同的查询计划,您可能会幸运地得到其中一个。不过,最好的解决方案是有适当的索引。查询的另一个结构是不存在。在某些情况下,这可以执行得更快:
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
);
这将很好地利用样本(客户机,记录日期)
上的索引(如果有的话)
另外,另一件事是保持
select client, max(recordDate),
max(Amount) keep (dense_rank first order by recordDate desc)
from sample s
group by client;
此版本假设每个客户机只有一个最大记录日期(您的原始查询不作此假设)
这些查询(加上dnoeth的查询)都应该有不同的查询计划,您可能会幸运地得到其中一个。不过,最好的解决方案是有适当的索引。谢谢。我刚刚尝试过,不幸的是,秩解要慢得多:13秒,而不是问题中的解的2秒。分析函数row_number()通常是我的goto方法(类似于使用像dnoeth那样的秩()),通常比问题中显示的方法快,因为它只需要一次数据传递,所以你的结果出乎意料。你是使用解释计划还是仅仅使用时间安排?谢谢。我刚刚尝试过,不幸的是,秩解要慢得多:13秒,而不是问题中的解的2秒。分析函数row_number()通常是我的goto方法(类似于使用像dnoeth那样的秩()),通常比问题中显示的方法快,因为它只需要一次数据传递,所以你的结果出乎意料。你是使用解释计划还是仅仅使用时间安排?谢谢。我刚刚尝试过,不幸的是,秩解要慢得多:13秒,而不是问题中的解的2秒。分析函数row_number()通常是我的goto方法(类似于使用像dnoeth那样的秩()),通常比问题中显示的方法快,因为它只需要一次数据传递,所以你的结果出乎意料。你是使用解释计划还是仅仅使用时间安排?谢谢。我刚刚尝试过,不幸的是,秩解要慢得多:13秒,而不是问题中的解的2秒。分析函数row_number()通常是我的goto方法(类似于使用像dnoeth那样的秩()),通常比问题中显示的方法快,因为它只需要一次数据传递,所以你的结果出乎意料。你是使用解释计划还是仅仅使用时间安排?谢谢。第一个建议需要很长时间,第二个建议第一次运行需要17秒,第二次运行需要7秒。比“古典”慢,但我学到了一些东西:-)@iDevlop。如果索引正确,第一个可能是最快的。我很惊讶keep
比aggregation/join方法慢。有趣。我在保留
方面运气不错。谢谢。第一个建议需要很长时间,第二个建议第一次运行需要17秒,第二次运行需要7秒。比“古典”慢,但我学到了一些东西:-)@iDevlop。如果索引正确,第一个可能是最快的。我很惊讶keep
比aggregation/join方法慢。有趣。我在保持
性能方面运气不错