Amazon Redshift存储过程中GETDATE()函数调用结果被缓存的问题排查及解决方案咨询
解决Redshift存储过程中GETDATE()缓存的问题
你遇到的这个问题是Redshift对存储过程内GETDATE()的特殊缓存机制导致的——哪怕关闭了会话级结果缓存,直接在PL/pgSQL里赋值GETDATE()的话,这个值会在存储过程首次执行时被缓存,后续调用都会复用这个缓存值,完全达不到实时获取时间的目的。
解决方案:用动态SQL获取实时时间戳
要绕过这个缓存,你需要通过动态SQL来执行GETDATE(),而不是直接赋值。这样每次执行到这一步时,Redshift都会重新计算当前时间,拿到实时的时间戳。
修改后的测试存储过程示例:
create or replace procedure tests.test_getdate_cache() as $$ declare ts timestamp; f float; begin -- 通过动态SQL获取实时开始时间 execute 'select getdate()' into ts; raise info 'START - getdate()=[%]', ts; FOR i IN 1..10000000 LOOP f:= i * 1234.4234; END LOOP; -- 再次通过动态SQL获取实时结束时间 execute 'select getdate()' into ts; raise info 'END - getdate()=[%]', ts; end; $$ LANGUAGE plpgsql; /
为什么直接调用会被缓存?
Redshift的PL/pgSQL实现有个特定优化:对于非动态调用的函数(比如ts := getdate();这种写法),会在存储过程生成执行计划的阶段就解析并缓存这个值,后续调用存储过程时不会重新计算。哪怕GETDATE()本身是非确定性函数,也会被这套机制影响。
而用动态SQL执行时,Redshift会在每次运行到这行代码时,重新执行这条SQL语句,自然就能拿到实时的当前时间,绕过了之前的缓存逻辑。
验证效果
修改后多次调用存储过程,你会看到每次的START和END时间都是实时更新的,不会再出现重复的时间戳:
START - getdate()=[2021-03-09 13:30:15] END - getdate()=[2021-03-09 13:30:28] START - getdate()=[2021-03-09 13:30:30] END - getdate()=[2021-03-09 13:30:43]
内容的提问来源于stack exchange,提问作者Emanuel Oliveira
相关产品推荐
相关产品推荐

