【问题标题】:How to measure time difference in milliseconds in a function?如何在函数中测量以毫秒为单位的时间差?
【发布时间】:2021-12-19 21:38:03
【问题描述】:

我想计算开始时间(timestamptz 类型的变量)和我的函数完成时的NOW() 时刻之间的差异。

select * from _get_date_diff_ms(NOW(), NOW())

在 PG 13.3 中使用 supabase.io,我收到以下错误消息:

operator does not exist: timestamp with time zone - double precision"
CREATE OR REPLACE FUNCTION _get_date_diff_ms(p_begin_time timestamptz, p_end_time timestamptz)
RETURNS int AS
$$
    BEGIN
        RETURN ROUND ((
            EXTRACT (EPOCH FROM p_begin_time -
            EXTRACT (EPOCH FROM p_end_time)
        ) * 1000));
    END;
$$ LANGUAGE plpgsql;

【问题讨论】:

  • ROUND(EXTRACT(EPOCH FROM p_end_time - p_begin_time) *1000) 有效吗?请记住:now() 在事务中将始终具有相同的值:它的开始时间。另见EXTRACT, date_part
  • 你是对的。我在 SAME 函数 (p/lpgsql) 中获取开始和结束时间,我尝试了 clock_timestamp() 和 now(),他们给出了这个 DOUBLE PRECISION 错误
  • 计算 PL/PGSQL 函数所用时间(以毫秒为单位)的惯用方法是什么?从 BEGIN (start_time) 到 RETURN (end_time)?我想将此值存储到另一个名为 (search_history) 的表中的列中。谢谢

标签: postgresql plpgsql timing supabase


【解决方案1】:

我认为您正在寻找的是:



CREATE OR REPLACE FUNCTION public._get_date_diff_ms(p_begin_time timestamp with time zone)
 RETURNS integer
 LANGUAGE plpgsql
AS $function$
    BEGIN
        RETURN round((EXTRACT(EPOCH FROM clock_timestamp() - p_begin_time ) * 1000));
    END;                                                                                
$function$
;

 select _get_date_diff_ms(now() - interval '.5 sec');
 _get_date_diff_ms 
-------------------
              500

我在函数调用中抛出了一个负间隔来实际获得差异。各种时间函数的作用见Current time

【讨论】:

    【解决方案2】:
    operator does not exist: timestamp with time zone - double precision
    

    这只是因为括号错误。你的意思是写:

            RETURN ROUND ((
                EXTRACT (EPOCH FROM p_begin_time) -    -- !
                EXTRACT (EPOCH FROM p_end_time)
            ) * 1000);
    

    但是整个方法被打破了。现在已经指出now() 是 Postgres 事务中的一个稳定值。见:

    此外,出于您所表达的目的,从一开始就传递“开始时间”是没有意义的。

    • 您的意思是事务的开始时间:然后在函数中的任何位置使用now()
    • 或者你的意思是函数的开始时间:然后在函数的开头使用clock_timestamp()

    假设是后者,我建议:

    CREATE OR REPLACE FUNCTION public._get_date_diff_ms() -- no parameter
     RETURNS numeric  -- !
     LANGUAGE plpgsql AS
    $func$
    DECLARE
       _start_ts timestamptz := clock_timestamp();  -- !
    BEGIN
       PERFORM pg_sleep(1);   --  do something here (1 sec example)
       RETURN round(1000 * EXTRACT(epoch FROM clock_timestamp() - _start_ts), 3);
    END                                                                                
    $func$;
    

    呼叫:

    test=> SELECT public._get_date_diff_ms();
     _get_date_diff_ms 
    -------------------
              1003.440
    

    我用 3 个小数位返回 numeric 而不是 integer 以捕获微秒。否则,对于许多快速操作,它只会报告 0。

    见:

    【讨论】:

    • 这是我根据此处的答案汇总的解决方案。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多