【问题标题】:How to estimate execution cost of function in pgsql?如何估算pgsql中函数的执行成本?
【发布时间】:2022-12-12 10:30:20
【问题描述】:

我正在尝试定义自定义函数,我想知道如何计算该函数的估计成本

https://www.postgresql.org/docs/current/sql-createfunction.html

我尝试给出不同的成本函数值,但无法找到如何估算该成本。

【问题讨论】:

    标签: postgresql plpgsql


    【解决方案1】:

    如果我足够关心打扰,我会做实验。

    例如,如果您的函数采用双精度,您可以比较:

    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 但我显着增加了查询的执行时间,如果我将这个函数添加为查询的一部分。
    • @AmarjeetKapoor 您可以附上一个"planner support function"(我认为)可以在返回估算值之前查看输入。但是通常在计划时无法获得实际输入,因为它来自专栏或其他内容,这既限制了您可以做的事情,又使您很难做到。您是否正在尝试解决实际问题,或者您只是想让事情变得整洁?
    【解决方案2】:

    postgresql 用于计算解释成​​本的公式加上下面解释的一些示例:

    SELECT 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)
    

    如果 COST 0.0001 AND 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; 的一部分
    • 阅读我存放在这里的书籍后,我发现了您可能需要的精确计算,这将给出解释分析的确切成本,它是 postgresql 公式:SELECT relpagescurrent_setting('seq_page_cost')::数字 + reltuplescurrent_setting('cpu_tuple_cost')::numeric as cost FROM pg_class WHERE relname='tablename';
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-27
    • 2020-06-04
    • 2013-03-24
    • 1970-01-01
    相关资源
    最近更新 更多