我有一个货币表和一个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。
答案 0 :(得分:0)
您没有标记您正在使用的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 < ?
条件可能会有所帮助。
答案 1 :(得分:0)
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上建立索引也是非常重要的,否则什么都不会使你的查询变得快速。
我还认为所提出的查询的性能类似,但我认为它略有简化。