PostgreSQL 12 preview - CTE 增强,支持用户语法层控制 materialized 优化

本文涉及的产品
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
简介: 标签 PostgreSQL , CTE , materialized , not materialized , push down 背景 PostgreSQL with 语法,能跑非常复杂的SQL逻辑,包括递归,多语句物化计算等。 在12以前的版本中,WITH中的每一个CTE(common table express),都是直接进行物化的,也就是说外层的条件不会推到CTE(物化节点)里

标签

PostgreSQL , CTE , materialized , not materialized , push down


背景

PostgreSQL with 语法,能跑非常复杂的SQL逻辑,包括递归,多语句物化计算等。

在12以前的版本中,WITH中的每一个CTE(common table express),都是直接进行物化的,也就是说外层的条件不会推到CTE(物化节点)里面去。

这么做对于insert,update,delete的CTE以及递归WITH语句,都是稀疏平常的。但是对于select CTE,外面的条件推到CTE里面,可能能够大幅降低扫描。

因此PG 12开始,提供了用户选择

with NOT MATERIALIZED (不使用物化,允许外面条件推进去)  
  
with MATERIALIZED (使用物化)  
Allow user control of CTE materialization, and change the default behavior.  
  
Historically we've always materialized the full output of a CTE query,  
treating WITH as an optimization fence (so that, for example, restrictions  
from the outer query cannot be pushed into it).  This is appropriate when  
the CTE query is INSERT/UPDATE/DELETE, or is recursive; but when the CTE  
query is non-recursive and side-effect-free, there's no hazard of changing  
the query results by pushing restrictions down.  
  
Another argument for materialization is that it can avoid duplicate  
computation of an expensive WITH query --- but that only applies if  
the WITH query is called more than once in the outer query.  Even then  
it could still be a net loss, if each call has restrictions that  
would allow just a small part of the WITH query to be computed.  
  
Hence, let's change the behavior for WITH queries that are non-recursive  
and side-effect-free.  By default, we will inline them into the outer  
query (removing the optimization fence) if they are called just once.  
If they are called more than once, we will keep the old behavior by  
default, but the user can override this and force inlining by specifying  
NOT MATERIALIZED.  Lastly, the user can force the old behavior by  
specifying MATERIALIZED; this would mainly be useful when the query had  
deliberately been employing WITH as an optimization fence to prevent a  
poor choice of plan.  
  
Andreas Karlsson, Andrew Gierth, David Fetter  
  
Discussion: https://postgr.es/m/87sh48ffhb.fsf@news-spur.riddles.org.uk  

例子

在CTE中使用NOT MATERIALIZED,表示这个CTE不使用物化,外面的条件可以推到CTE中。

In particular, if there's an index on key, it will probably be used to fetch just the rows having key = 123. On the other hand, in

WITH w AS (  
    SELECT * FROM big_table  
)  
SELECT * FROM w AS w1 JOIN w AS w2 ON w1.key = w2.ref  
WHERE w2.key = 123;  

the WITH query will be materialized, producing a temporary copy of big_table that is then joined with itself — without benefit of any index.

This query will be executed much more efficiently if written as:

WITH w AS NOT MATERIALIZED (  
    SELECT * FROM big_table  
)  
SELECT * FROM w AS w1 JOIN w AS w2 ON w1.key = w2.ref  
WHERE w2.key = 123;  

参考

https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=608b167f9f9c4553c35bb1ec0eab9ddae643989b

https://www.postgresql.org/docs/devel/queries-with.html

 

免费领取阿里云RDS PostgreSQL实例、ECS虚拟机

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
23天前
|
SQL 自然语言处理 关系型数据库
MySQL的match匹配多个字符串的语法
【8月更文挑战第27天】MySQL的match匹配多个字符串的语法
170 67
|
25天前
|
监控 关系型数据库 数据库
PostgreSQL的索引优化策略?
【8月更文挑战第26天】PostgreSQL的索引优化策略?
47 1
|
3月前
|
SQL 关系型数据库 MySQL
MySQL数据库基础第一篇(SQL通用语法与分类)
MySQL数据库基础第一篇(SQL通用语法与分类)
|
3月前
|
存储 关系型数据库 MySQL
MySQL数据库的数据类型、语法和高级查询
MySQL数据库的数据类型、语法和高级查询
52 0
|
7天前
|
SQL 关系型数据库 MySQL
mysql的语法
mysql的语法
18 1
|
20天前
|
SQL 自然语言处理 关系型数据库
MySQL的match匹配多个字符串的语法
【8月更文挑战第29天】MySQL的match匹配多个字符串的语法
46 2
|
1月前
|
关系型数据库 MySQL Linux
数据类型和运算符(MySQL服务器的安装,MySQL客户端,数据类型,运算符,MySQL的语法规范)
无论是对于初学者还是有经验的开发者,了解MySQL的安装、客户端使用、数据类型、运算符和语法规范都是至关重要的。这不仅有助于高效地管理和查询数据,而且对于设计和实现数据库解决方案来说是基础工作。通过深入学习和实践这些知识,您可以更好地发挥MySQL数据库的强大功能。
22 2
|
1月前
|
SQL 关系型数据库 MySQL
INSERT INTO t_a.tableName SELECT * FROM t_b.tableName 如何通过定义一个list对象,包含多个tableName,循环执行前面的sql,用MySQL的语法写
【8月更文挑战第7天】INSERT INTO t_a.tableName SELECT * FROM t_b.tableName 如何通过定义一个list对象,包含多个tableName,循环执行前面的sql,用MySQL的语法写
24 5
|
1月前
|
监控 关系型数据库 数据库
如何优化PostgreSQL的性能?
【8月更文挑战第4天】如何优化PostgreSQL的性能?
80 7
|
20天前
|
SQL 关系型数据库 MySQL
SQL Server、MySQL、PostgreSQL:主流数据库SQL语法异同比较——深入探讨数据类型、分页查询、表创建与数据插入、函数和索引等关键语法差异,为跨数据库开发提供实用指导
【8月更文挑战第31天】SQL Server、MySQL和PostgreSQL是当今最流行的关系型数据库管理系统,均使用SQL作为查询语言,但在语法和功能实现上存在差异。本文将比较它们在数据类型、分页查询、创建和插入数据以及函数和索引等方面的异同,帮助开发者更好地理解和使用这些数据库。尽管它们共用SQL语言,但每个系统都有独特的语法规则,了解这些差异有助于提升开发效率和项目成功率。
88 0