我有一个很长的查询(~200行),我已经嵌入了一个函数:
CREATE FUNCTION spot_rate(base_currency character(3),
contra_currency character(3),
pricing_date date) RETURNS numeric(20,8)
我是直接运行查询还是我得到类似结果和类似性能的函数。到目前为止一切都很好。
现在我有另一个长查询,如下所示:
SELECT x, sum(y * spot_rates.spot)
FROM (SELECT a, b, sum(c) FROM t1 JOIN t2 etc. (6 joins here)) AS table_1,
(SELECT
currency,
spot_rate(currency, 'USD', current_date) AS "spot"
FROM (SELECT DISTINCT currency FROM table_2) AS "currencies"
) AS "spot_rates"
WHERE
table_1.currency = spot_rates.currency
GROUP BY / ORDER BY
此查询在300毫秒内运行,在此阶段运行缓慢但足够快(考虑到行数和聚合操作,可能有意义)。
但是,如果我用等效查询替换spot_rate(currency, 'USD', current_date)
,它将在5秒内运行。
无论是使用函数还是等效查询,单独运行子查询都会在〜200ms内返回。
为什么查询比用作子查询时的函数运行得慢?
ps:我希望对这个通用问题有一个通用的答案 - 如果不是,我会发布更多细节,但创建一个人为的例子并不简单。
编辑:EXPLAIN ANALYZE在2个子查询和整个查询上运行
答案 0 :(得分:2)
只是猜测:您的查询范围表超出了join_collapse_limit,导致使用次优计划。
尝试将子查询体(相当于函数)移动到CTE中,以保持其完好无损。 (CTE总是被执行,并且永远不会被查询生成器/计划者分解)
将查询中的部分预先分析到(TEMP)表或物化视图中也可以帮助减少RTE的数量
join_collapse_limit
,但这会花费更多的计划时间,而且肯定有一个限制(可能的计划数量随着规模的增长呈指数级增长范围表。)