如何在pgsql中估算函数的执行成本?

3
2个回答

0

PostgreSQL使用的计算解释成本的公式以及以下一些解释示例,必须对表中的所有内容进行求和(索引、外键、序列): 参考资料:https://postgrespro.com/blog/pgsql/5969403

SELECT relname , relpages*current_setting('seq_page_cost')::numeric + 
reltuples*current_setting('cpu_tuple_cost')::numeric as cost
FROM pg_class
--WHERE relname='tablename';

您可以使用EXPLAIN查看每个查询的CPU成本,注意这个值是静态的,并基于所使用的对象。

    CREATE OR REPLACE FUNCTION a() RETURNS SET OF INTEGER AS $$
 SELECT 1;
$$
LANGUAGE SQL;
EXPLAIN SELECT * FROM a() CROSS JOIN (Values(1),(2),(3)) as foo;

Nested Loop (cost=0.25..47.80 rows=3000 width=8)
 -> Function Scan on a (cost=0.25..10.25 rows=1000 width=4)
 -> Materialize (cost=0.00..0.05 rows=3 width=4)
 -> Values Scan on "*VALUES*" (cost=0.00..0.04 rows=3 width=4)
(4 rows)

如果两个成本分别为0.0001和10000的函数同时在SELECT语句的谓词中执行,查询规划器将首先执行成本为0.0001的函数,然后才执行成本为10000的条件,就像下面的示例一样。
EXPLAIN SELECT * FROM pg_language WHERE lanname ILIKE '%sql%' AND slow_
function(lanname)AND fast_function(lanname);
 QUERY PLAN
-------------------------------------------------------------------------
Seq Scan on pg_language (cost=0.00..101.05 rows=1 width=114)
 Filter: (fast_function(lanname) AND (lanname ~~* '%sql%'::text) AND 
slow_function(lanname))
(2 rows)

我的函数没有显示在查询解释中,它们是select f(table) from table;的一部分。 - Amarjeet Kapoor
经过阅读我这里存储的一些书籍,我发现了您可能正在寻找的精确计算,这将从解释分析中给出确切的成本,它是postgresql公式:SELECT relpages * current_setting('seq_page_cost')::numeric + reltuples * current_setting('cpu_tuple_cost')::numeric as cost FROM pg_class WHERE relname ='tablename'; - mwalter

0

如果我在乎并且想要尝试,我会进行实验。

例如,如果您的函数需要双精度,可以进行比较:

explain analyze select sqrt(x::double precision) from generate_series(1,1000000) f(x);

explain analyze select your_func(x::double precision) from generate_series(1,1000000) f(x);

然后找到成本设置,使得成本估计的比率与实际时间的比率大致相同。

您可以尝试减去generate_series和cast的基线成本,但如果您的函数增加的时间非常小,以至于需要这样的精度,那么它可能足够小,只需将成本设置为1,不必担心它。


谢谢,我尝试了不同的值进行实验,但我的函数的实时复杂度取决于输入,我得到了非常不同的执行时间。如果我单独运行此函数,它的成本显示为0.00....01,但如果我将此函数作为查询的一部分添加,则会显著增加查询的执行时间。 - Amarjeet Kapoor
@AmarjeetKapoor 您可以附加一个 "planner support function",它(我认为)可以在返回估计值之前查看输入。但通常实际输入在规划时不可用,因为它来自列或其他东西,这限制了您可以做的事情,并使其非常难以完成。您是否正在尝试解决实际问题,还是只想使事情变得整洁有序? - jjanes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接