skip to Main Content

I am trying to define custom function and I wanted to find how can I calculate estimated cost of that function

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

I tried giving different values of cost function but unable to find to find how to estimate that cost.

2

Answers


  1. The formula postgresql uses for calculate the explain cost plus some examples of explain below,is necessary to sum everything from the table (indexes , foreign keys ,sequence):
    references : 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';
    

    You can use EXPLAIN to see the cost of CPU from each query,notice that this value is static and based on the objects used.

        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)
    

    If two functions with COST 0.0001 AND 10000 get executed on the same time as the predicate of a SELECT statement the query planner will execute first the function of cost 0.0001 and only later the 10000 cost condition as you can see in this example below.

    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)
    
    Login or Signup to reply.
  2. If I cared enough to bother, I would do it experimentally.

    For example, if your function takes double precision, you could compare:

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

    to

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

    And then find the cost setting that makes the ratio of the cost estimates about match the ratio of the actual times.

    You could try to subtract the baseline costs of the generate_series and the cast, but if the added time of your function is so small that it warrants such precision, then it is probably small enough to just make the cost 1 and not worry about it.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search