繁体   English   中英

在子查询中执行包含max-aggregate的SQL语句的最有效方法

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM