PostgreSQL 11执行CREATE TABLE WITH NO DATA速度极慢问题咨询
PostgreSQL 11 两种空表复制语法性能差异原因
两种写法的语义完全一致,均为仅复制原表结构不复制数据,性能差异来自PostgreSQL 11版本对两类语法的优化支持程度不同:
- 第一种写法
CREATE TABLE IF NOT EXISTS my_temp_table AS TABLE my_enormous_table WITH NO DATA的性能问题核心是PostgreSQL 11 未对该语法实现针对性优化:TABLE 表名是SELECT * FROM 表名的语法糖,PG11的查询规划器没有将WITH NO DATA的语义下推到查询规划阶段,仍然会按照完整查询的逻辑生成执行计划,首先触发对原表的统计信息查询、元数据校验,甚至会启动对原表的顺序扫描流程,虽然最终不会返回数据,但扫描启动阶段的IO开销在原表体量极大时会被无限放大,也就是你EXPLAIN结果中看到的Seq Scan执行计划- 如果原表存在大量死元组、统计信息过时、或者表对应的磁盘数据未被缓存,这个预扫描的耗时会进一步拉长,最终出现数分钟的执行延迟
- 第二种写法
CREATE TABLE ... (SELECT * FROM my_enormous_table WHERE FALSE)的性能优势来自PG的通用常量折叠优化:
查询规划器可以直接识别WHERE FALSE是恒假条件,无需访问任何表数据即可确定返回结果为空,直接跳过原表的扫描、统计信息校验等所有IO操作,仅提取原表的结构元数据生成新表,因此执行速度极快
补充说明:该优化缺失问题仅存在于PostgreSQL 11及更早版本,PostgreSQL 12及更高版本已经对
CREATE TABLE AS TABLE ... WITH NO DATA的执行逻辑做了优化,不会再触发不必要的顺序扫描,两种写法性能一致。
内容的提问来源于stack exchange,提问作者PANDA Stack
相关产品推荐
相关产品推荐

