[英]Most efficient way to perform an SQL-Statement containing a max-aggregate in the sub-query
我有一个货币表和一个exchange_rate_log表。 后者包含超过十亿条记录。 exchange_rate_log表包含最近几年许多货币的交易汇率。
现在,我必须为所有可用货币(以表货币)选择给定exchange_currency和给定日期的最新有效交易汇率。
因此,如果给定的exchange_currency为“ EUR”,日期为昨天。 结果会将所有可用货币的最新交易从时间表“ exchange_rate_log”中的第一个可用条目返回到时间窗口中的“ EUR”,直到昨天。
以下查询显示了获得答案的可能方法。 但是,给定的查询不能很好地执行。
SELECT cur.name, log.price, log.valid_at
FROM currency cur
JOIN exchange_rate_log log ON (cur.id = log.currency_id)
WHERE log.valid_at = (SELECT max(log2.valid_at)
FROM exchange_rate_log log2
WHERE log2.currency_id = cur.id
AND log2.exchange_currency = ?
AND log2.valid_at < ?);
是否有可能通过适应性更好的查询获得相同的结果? 是否可以创建索引来提高上述查询的性能?
备注:目标dbms是Oracle。
您没有标记正在使用的DBMS,因此这是使用标准SQL中的RANK:
select *
from
(
SELECT cur.name, log.price, log.valid_at,
RANK()
OVER (PARTITION BY cur.id
order by valid_at DESC) as rnk
FROM currency cur
JOIN exchange_rate_log log on (cur.id = log.currency_id)
WHERE log.exchange_currency = ?
AND log.valid_at < ?
) dt
where rnk = 1;
是否更有效取决于DBMS的优化功能。
否则添加log.valid_at < ?
原始查询的条件可能会有所帮助。
SELECT TOP 1
cur.name, log.price, log.valid_at
FROM exchange_rate_log log
INNER JOIN currency cur
ON log.currency_id = cur.id
WHERE log.exchange_currency = ?
AND log.valid_at < ?
ORDER BY log.valid DESC;
在log.valid和log.exchange_currency上建立索引也很重要,否则没有什么可以使您的查询快速进行。
我还认为呈现的查询的性能将相似,但我认为它略有简化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.