PostgreSQL 12起支持CTE物化控制,物化CTE先计算并存储结果供后续查询使用,而非物化CTE则内联到主查询中优化执行。

PostgreSQL 中的 CTE(Common Table Expression)默认情况下是 不物化 的,这意味着它在执行时可能被内联展开,而不是作为一个独立的结果集先计算出来。但从 PostgreSQL 12 开始,引入了对 CTE 物化的控制能力。理解物化与非物化 CTE 的区别,有助于优化查询性能和避免意外行为。
什么是物化 CTE?
物化 CTE 指的是数据库在执行主查询前,先将 CTE 中的查询结果完整地计算并存储在一个临时空间中,后续主查询直接从这个“缓存”结果读取数据。这种行为类似于创建一个临时表。
例如:
Shakker
多功能AI图像生成和编辑平台
103 查看详情
WITH materialized_cte AS MATERIALIZED ( SELECT id, name FROM users WHERE created > ‘2023-01-01’ ) SELECT * FROM materialized_cte WHERE name LIKE ‘A%’;
这里使用 MATERIALIZED 关键字明确告诉 PostgreSQL 要物化该 CTE。
什么是非物化 CTE?
非物化 CTE 不会提前生成结果,而是将其逻辑“内联”到主查询中,等价于把 CTE 的定义直接替换进主查询语句中进行优化。这可能导致 CTE 被多次执行(如果引用多次),但也可能获得更好的整体执行计划。
例如:
WITH not_materialized AS NOT MATERIALIZED ( SELECT id FROM logs WHERE status = ‘error’ ) SELECT l.* FROM logs l JOIN not_materialized n ON l.id = n.id;
此时 PostgreSQL 可能选择将条件合并,直接走索引扫描,而不实际构建中间结果集。
关键区别对比
执行时机:物化 CTE 先执行并保存结果;非物化则参与整体查询重写和优化。性能影响:复杂过滤或聚合的 CTE 物化后可避免重复计算;但简单条件内联可能更快。副作用体现:若 CTE 包含函数调用(如 random() 或 now()),物化保证值一致,非物化可能导致每次引用不同结果。引用次数影响:非物化 CTE 若被引用多次,可能被执行多次;物化只执行一次。
如何控制物化行为?
PostgreSQL 提供显式语法来控制:
WITH cte AS MATERIALIZED (...) :强制物化WITH cte AS NOT MATERIALIZED (...) :禁止物化(尝试内联)WITH cte AS (...) :由优化器决定(PostgreSQL 12+)
注意:在旧版本(
基本上就这些。合理利用物化控制,可以提升查询稳定性或性能,特别是在涉及随机函数、序列访问、或昂贵子查询时,明确指定是否物化更安全可靠。
以上就是postgresql物化cte与非物化区别在哪里_postgresqlcte行为解析的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1084834.html
微信扫一扫
支付宝扫一扫