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
相关产品推荐
相关产品推荐

