PostgreSQL 12 新特性解读之二| CTE支持Inlined With Queries 原作者:谭峰 创作时间:2019-09-05 14:16:09+08 |
wangliyun 发布于2019-09-06 08:16:09
![]() ![]() ![]() ![]() ![]() |
作者介绍
谭峰,网名francs,《PostgreSQL实战》作者之一,《PostgreSQL 9 Administration Cookbook》译者之一,PostgreSQL 中文社区委员,致力于PostgreSQL技术分享,博客 https://postgres.fun
PostgreSQL 的 CTE( common table expressions ) 支持较复杂的查询,比如递归查询等场景, 12 版本之前 CTE 的 WITH 语句都是直接物化的,也就是说 WITH 语句执行一次并保持到一个类似的临时表中,供 WITH 语句外层的SQL引用,当 INSERT/UPDATE/DELETE 做CTE的 WITH 语句时是非常恰当的。
PostgreSQL 12 版本的一个重要特性是 CTE 支持 Inlined WITH queries,也就是说当 SELECT 做为CTE 的 WITH 语句时,支持将 WITH 语句中的查询条件下推到外层SQL中,从而提升 CTE 语句性能。
发行说明
Allow common table expressions (CTE) to be inlined in later parts of the query (Andreas Karlsson, Andrew Gierth, David Fetter, Tom Lane)
Specifically, CTEs are inlined if they are not recursive and are referenced only once later in the query. Inlining can be prevented by specifying MATERIALIZED, and forced by specifying NOT MATERIALIZED. Previously, CTEs were never inlined and were always evaluated before the rest of the query.
根据手册说明, CTE 的 Inlined WITH Queries 需要满足以下条件:
1.Are not recursive,非递归
2.Are referenced only once later in the query,外层查询仅调用一次
补丁说明
Tom Lane 大神提交的补丁,如下
commit: 608b167f9f9c4553c35bb1ec0eab9ddae643989b
author: Tom Lane <tgl@sss.pgh.pa.us>
date: Sat, 16 Feb 2019 16:11:12 -0500
Allow user control of CTE materialization, and change the default behavior.
Historically we haveve 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 iss 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
根据手册说明和补丁说明不一定能很好理解,下面通过实验演示。
环境准备
测试环境为1台8核16G虚拟机,创建测试表并插入 500 万数据,如下:
CREATE TABLE t (id int4, name text);
INSERT INTO t(id,name) SELECT n, 'francs_' || n
FROM generate_series(1,5000000) n;
ALTER TABLE t ADD PRIMARY KEY (id);
构造一条 SELECT 做为 CTE 的 WITH 语句,如下:
WITH x AS (
SELECT * FROM t WHERE t > 1
)
SELECT * FROM x where id=1;
PostgreSQL 11 测试
11 版本测试如下:
postgres=# EXPLAIN ANALYZE WITH x AS (
SELECT * FROM t
)
SELECT * FROM x where id=1;
QUERY PLAN
--------------------------------------------------------------------------
CTE Scan on x (cost=81838.00..194338.00 rows=25000 width=36) (actual time=0.057..1557.140 rows=1 loops=1)
Filter: (id = 1)
Rows Removed by Filter: 4999999
CTE x
-> Seq Scan on t (cost=0.00..81838.00 rows=5000000 width=36) (actual time=0.050..525.329 rows=5000000 loops=1
)
Planning Time: 0.128 ms
Execution Time: 1591.979 ms
(7 rows)
Time: 1592.534 ms (00:01.593)
从执行计划看出分两步走,首先是在表 t 上做全表扫描,之后进行 CTE Scan 并过滤 id=1 的记录,以上并没有走索引,执行时间为 1592.534 ms,性能很低。
PostgreSQL 12 测试
12 版本测试如下:
postgres=# EXPLAIN ANALYZE WITH x AS (
SELECT * FROM t
)
SELECT * FROM x where id=1;
QUERY PLAN
--------------------------------------------------------------------------
Index Scan using t_pkey on t (cost=0.43..8.45 rows=1 width=36) (actual time=0.021..0.022 rows=1 loops=1)
Index Cond: (id = 1)
Planning Time: 0.087 ms
Execution Time: 0.043 ms
(4 rows)
Time: 0.469 ms
从执行计划看出,将 WITH 语句中的条件( id=1 ) 下推到了外层SQL中,这样直接走了 Index Scan,执行时间降为 0.469 ms,大辐提升了 CTE 语句性能。
支持用户控制 MATERIALIZED
12 版本用户可在 CTE 语句中控制是否使用物化(MATERIALIZED)。
以下 CTE 语句设置使用 MATERIALIZED,如下:
postgres=# EXPLAIN ANALYZE WITH x AS MATERIALIZED (
SELECT * FROM t
)
SELECT * FROM x where id=1;
QUERY PLAN
--------------------------------------------------------------------------
CTE Scan on x (cost=81837.99..194337.97 rows=25000 width=36) (actual time=0.023..1607.012 rows=1 loops=1)
Filter: (id = 1)
Rows Removed by Filter: 4999999
CTE x
-> Seq Scan on t (cost=0.00..81837.99 rows=4999999 width=18) (actual time=0.015..556.583 rows=5000000 loops=1)
Planning Time: 0.245 ms
Execution Time: 1640.071 ms
(7 rows)
Time: 1641.072 ms (00:01.641)
以下 CTE 语句设置不使用 MATERIALIZED,如下:
postgres=# EXPLAIN ANALYZE WITH x AS NOT MATERIALIZED (
SELECT * FROM t
)
SELECT * FROM x where id=1;
QUERY PLAN
--------------------------------------------------------------------------
Index Scan using t_pkey on t (cost=0.43..8.45 rows=1 width=18) (actual time=0.072..0.074 rows=1 loops=1)
Index Cond: (id = 1)
Planning Time: 0.134 ms
Execution Time: 0.099 ms
(4 rows)
Time: 0.801 ms
总结
PostgreSQL 12 版本的 CTE 支持 Inlined WITH Queries 特性,由于 WITH 查询语句的条件可以外推到外层查询,避免中间结果数据产生),同时使用相关索引,从而大辐提升 CTE 性能。
参考
1.[Postgres 12 highlight - WITH clause and materialization]
(https://paquier.xyz/postgresql-2/postgres-12-with-materialize/)
2.[PostgreSQL 12 preview - CTE 增强,支持用户语法层控制 materialized 优化]
(https://github.com/digoal/blog/blob/master/201903/20190309_04.md)
阅读源文
https://postgres.fun/20190807110800.html
请在登录后发表评论,否则无法保存。
1# __
xcvxcvsdf 回答于 2024-11-13 15:00:37+08
http://ruanwen.xztcxxw.cn/tdx/
http://huaguang.jxtcbmw.cn/baqz/
https://gyqchengxi.tiancebbs.cn/
https://guanghe.tiancebbs.cn/
http://ruanwen.xztcxxw.cn/changji/
https://jc.tiancebbs.cn/
http://ruanwen.xztcxxw.cn/dzdqhs/
http://jinqiang.ahtcbmw.cn/hljhg/
http://yz.cqtcxxw.cn/pingliang/
http://fs.shtcxxw.cn/dongfang/
http://jingren.hftcbmw.cn/jinganqu/
http://huilong.sctcbmw.cn/sdly/
http://tuiguang.hntcxxw.cn/shfw/
http://yuanbang.tjtcbmw.cn/chuxiong/
http://wutai.cqtcxxw.cn/zunyi/
http://jingren.hftcbmw.cn/hengyang/
http://huaguang.jxtcbmw.cn/xzrhc/
2# __
xcvxcvsdf 回答于 2024-11-12 06:19:36+08
https://aihuishou.tiancebbs.cn/store/2775/info-page-298.html
https://gliao.tiancebbs.cn/qths/455651.html
https://wuhuaxian.tiancebbs.cn/qths/470086.html
https://dl.tiancebbs.cn/qths/453376.html
https://aihuishou.tiancebbs.cn/sh/2081.html
https://aihuishou.tiancebbs.cn/store/2775/info-page-229.html
https://sh.tiancebbs.cn/hjzl/467448.html
https://zulin.tiancebbs.cn/sh/1720.html
https://aihuishou.tiancebbs.cn/sh/1884.html
https://aihuishou.tiancebbs.cn/sh/2592.html
https://changshushi.tiancebbs.cn/hjzl/460037.html
https://zulin.tiancebbs.cn/sh/4729.html
https://aihuishou.tiancebbs.cn/sh/2295.html
https://sz.tiancebbs.cn/jcdl-IC-/57002.html
https://ganzi.tiancebbs.cn/qths/453314.html
https://aihuishou.tiancebbs.cn/sh/1744.html
https://aihuishou.tiancebbs.cn/sh/1345.html
3# __
xcvxcvsdf 回答于 2024-10-31 22:24:17+08
http://taiying.njtcbmw.cn/jsha/
https://jiangwan.tiancebbs.cn/
http://fs.shtcxxw.cn/wuzhou/
https://tzqbghd.tiancebbs.cn/
http://bjtcxxw.cn/gzmdnc/
http://cf.lstcxxw.cn/bjtz/
https://sjsqlianhuahe.tiancebbs.cn/
https://aihuishou.tiancebbs.cn/hkqsh/
http://nalei.zjtcbmw.cn/yi-chun/
https://huangge.tiancebbs.cn/
https://cwqzhoubian.tiancebbs.cn/
http://nalei.zjtcbmw.cn/rizhao/
http://js.sytcxxw.cn/aba/
http://wutai.cqtcxxw.cn/linzhi/
http://huaguang.jxtcbmw.cn/bmjz/
http://ty.cqtcxxw.cn/rikaze/
http://nalei.zjtcbmw.cn/sddz/
4# __
xcvxcvsdf 回答于 2024-10-17 16:24:33+08
http://gx.lztcxxw.cn/dp/
http://shimai.zjtcbmw.cn/qinzhou/
http://bjtcxxw.cn/cdq/
https://jdxqshi.tiancebbs.cn/
https://pdxqzhuqiao.tiancebbs.cn/
http://shimai.zjtcbmw.cn/foshan/
http://tuiguang.hntcxxw.cn/gzzy/
https://xsqchengdong.tiancebbs.cn/
https://xhqqita.tiancebbs.cn/
https://yqqgaoxin.tiancebbs.cn/
https://zhzhoubian.tiancebbs.cn/
http://fs.shtcxxw.cn/qiandongnan/
http://fs.shtcxxw.cn/jinshanqu/
http://huaguang.jxtcbmw.cn/xian/
http://tuiguang.hntcxxw.cn/nanchang/
http://km.lstcxxw.cn/yantai/
https://rychengdong.tiancebbs.cn/
5# __
xiaowu 回答于 2024-04-24 10:38:00+08
水浒传的作者是谁:https://www.nanss.com/xuexi/19850.html 健康安全知识:https://www.nanss.com/yinshi/18731.html 关于时间的谜语:https://www.nanss.com/shenghuo/20053.html 司法鉴定申请书:https://www.nanss.com/shenghuo/18677.html 自然数包括什么:https://www.nanss.com/xuexi/18450.html 学钢琴的最佳年龄:https://www.nanss.com/wenti/19514.html 邯郸学步的故事:https://www.nanss.com/yuedu/18553.html 五官是哪五官:https://www.nanss.com/shenghuo/18551.html 平安夜送女朋友什么礼物:https://www.nanss.com/wenti/19880.html cue是什么意思:https://www.nanss.com/wenti/19807.html 许地山作者简介:https://www.nanss.com/shenghuo/19382.html 爱迪生发明了什么:https://www.nanss.com/shenghuo/18544.html 大智若愚是什么意思:https://www.nanss.com/xuexi/18232.html 科学教研组工作总结:https://www.nanss.com/gongzuo/18590.html 幼儿园家长教育心得:https://www.nanss.com/yuer/19659.html 选调生工作总结:https://www.nanss.com/gongzuo/19711.html 一年级教学工作总结:https://www.nanss.com/gongzuo/20090.html 关于申请经费的请示:https://www.nanss.com/gongzuo/19745.html 长江多长:https://www.nanss.com/shenghuo/18363.html 医患沟通:https://www.nanss.com/shenghuo/20110.html 慈禧是谁的老婆:https://www.nanss.com/wenti/20000.html 肯德基是哪个国家的:https://www.nanss.com/shenghuo/19425.html 宫保鸡丁的家常做法:https://www.nanss.com/yinshi/19858.html 氧气的化学性质:https://www.nanss.com/xuexi/18966.html 天元术的主要贡献者:https://www.nanss.com/xuexi/18249.html 上甘岭观后感:https://www.nanss.com/xuexi/18380.html 1g流量等于多少mb:https://www.nanss.com/shenghuo/18961.html 读书的乐趣:https://www.nanss.com/xuexi/19087.html 工作设想怎么写:https://www.nanss.com/gongzuo/20095.html 腊八蒜的腌制方法:https://www.nanss.com/yinshi/19846.html
发表评论:
扫码关注
© PostgreSQL中文社区 ... (自2010年起)