将T-SQL更新语句转PostgreSQL:能否用ctid替代主键?
用ctid替代主键更新PostgreSQL临时表的可行性分析
首先明确:对于你这种会话级的临时表场景,完全可以用ctid替代主键完成更新操作,而且你的待验证语句是有效的,但可以进一步简化。
关于ctid的稳定性(针对临时表)
你提到VACUUM会改变ctid,但临时表的特性决定了这个风险几乎不存在:
- 临时表仅属于当前会话,PostgreSQL不会对临时表自动执行VACUUM操作(包括自动清理)
- 除非你手动在当前会话内对该临时表执行
VACUUM FULL,否则在整个会话生命周期里,ctid的值是稳定的 - 就算你手动执行VACUUM,只要是在更新操作之前完成,更新过程中ctid也不会发生变化
你的待验证语句优化
你的语句逻辑是对的,但其实不需要额外自连接table_1,可以简化为更高效的写法:
UPDATE table_1 SET col_1 = tt.val FROM table_2 tt WHERE table_1.col_2 = tt.col_2;
这个写法和你用ctid的版本效果完全一致,而且避免了多余的表扫描,性能更优。
为什么你的原语句也能工作
你写的带ctid的语句本质上是通过自连接+ctid定位到要更新的行,逻辑是通顺的:
UPDATE table_1 SET col_1 = tt.val FROM table_1 t INNER JOIN table_2 tt ON t.col_2 = tt.col_2 WHERE table_1.ctid = t.ctid;
但这种写法多了一次对table_1的扫描,属于冗余操作,所以更推荐简化后的版本。
总结
- 临时表场景下用ctid替代主键是安全可行的
- 优先使用直接关联
table_2的简化更新语句,无需借助ctid - 永久表不建议依赖ctid,但临时表完全没问题
内容的提问来源于stack exchange,提问作者e1s
相关产品推荐
相关产品推荐

