You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL中now()返回值始终相同?代码计时问题及正确方法咨询

PostgreSQL 计时踩坑:为什么now()测不出真实耗时?

这是个非常常见的PostgreSQL时间函数误区,我来给你把问题说透:

为什么now()不管用?

你踩的核心坑是:now()(以及别名transaction_timestamp())返回的是当前事务的启动时间,在整个事务执行期间,它的值是完全固定的。不管你在代码里调用多少次now(),拿到的都是事务一开始的那个时间戳——这就是为什么你连续打印5次now()全是同一个值,计时差永远是00:00:00的原因。

PostgreSQL这么设计是为了保证事务内时间的一致性,避免因为时间变化导致逻辑异常,但显然不适合用来做代码执行的计时。

正确的计时方式

要精确测量代码片段的执行耗时,你需要用clock_timestamp(),它会实时返回当前的系统时间,每次调用都会重新获取,能真实反映时间的流逝。

另外还有两个相关函数可以了解下,方便你根据场景选择:

  • statement_timestamp():返回当前SQL语句的启动时间,在单个PL/pgSQL块里它的值也是固定的,适合测量整个语句的耗时,但不适合片段计时。
  • transaction_timestamp():和now()完全等价,事务级的固定时间。

修改后的计时代码示例

把你的DO块改成这样,就能得到真实的耗时了:

DO $$ 
DECLARE 
  PROGRAMM_TIME_ELAPSED TIMESTAMP;
  VALUES_COUNT INT := 0;
BEGIN
  SELECT INTO PROGRAMM_TIME_ELAPSED clock_timestamp();
  -- 这里替换成你的实际业务代码
  FOR i IN 1..10000 LOOP
    VALUES_COUNT := VALUES_COUNT + 1;
  END LOOP;
  raise notice '% values created in %', VALUES_COUNT, clock_timestamp() - PROGRAMM_TIME_ELAPSED;
END $$;

测试实时时间的代码也换成clock_timestamp(),就能看到每次的时间差了:

raise notice '%', clock_timestamp();
raise notice '%', clock_timestamp();
raise notice '%', clock_timestamp();
raise notice '%', clock_timestamp();
raise notice '%', clock_timestamp();

总结一下适用场景

  • 测整个事务耗时:用now() / transaction_timestamp()
  • 测单个SQL语句耗时:用statement_timestamp()
  • 测代码片段的精确执行时间:必须用clock_timestamp()

内容的提问来源于stack exchange,提问作者DIBits

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:46:37