PostgreSQL CTE语句与materialized
PostgreSQL with语句功能可谓十分强大,可以优化很多复杂的查询,实现递归等等。不过with虽好,可还是不要乱用。
因为在PG12之前,with语句都是通过将子查询先进行物化,这就导致了一个问题:with子查询外的条件无法内推到里面。
我们看看PG12之前:
从执行计划可以看到,先对t1表进行全表扫描了一遍,然后再去进行过滤。
postgres=# explain analyze with c1 as (select * from t1) select * from c1 where id = 100;QUERY PLAN
---------------------------------------------------------------------------------------------------------------CTE Scan on c1 (cost=184.00..409.00 rows=50 width=36) (actual time=0.096..5.711 rows=1 loops=1)Filter: (id = 100)Rows Removed by Filter: 9999CTE c1-> Seq Scan on t1 (cost=0.00..184.00 rows=10000 width=37) (actual time=0.041..2.370 rows=10000 loops=1)Planning time: 0.122 msExecution time: 5.959 ms
(7 rows)
而到了PG12,提供了两个选项:
- with NOT MATERIALIZED (不使用物化,允许外面条件推进去)
- with MATERIALIZED (使用物化)
我们可以看下:
可以直接将id = 100的条件内推到with子句里面,还使用了索引扫描,这便是not MATERIALIZED带来的好处。
postgres=# explain analyze with c1 as (select * from t1) select * from c1 where id = 100;QUERY PLAN
------------------------------------------------------------------------------------------------------------Index Scan using idx_t1 on t1 (cost=0.29..8.30 rows=1 width=37) (actual time=0.035..0.036 rows=1 loops=1)Index Cond: (id = 100)Planning Time: 0.439 msExecution Time: 0.063 ms
(4 rows)
当然,既然还保留了原先的MATERIALIZED选项,自然也有它的好处。
那么对子查询直接物化的好处是什么呢?使用物化的好处是:如果是在每一次父查询的执行中它们通常只被计算一次,即使它们被父查询或兄弟WITH查询引用了超过一次,那么对于子查询本身代价很高的情况下。
这种情况下显然性能更佳:
WITH w AS (SELECT key, very_expensive_function(val) as f FROM some_table
)
SELECT * FROM w AS w1 JOIN w AS w2 ON w1.f = w2.f;
总结:
- with NOT MATERIALIZED:不使用物化,允许外面条件推进去,但是存在子查询被多次执行的情况。
- with MATERIALIZED:使用物化,不允许外面条件推进去,但是可以保证子查询只被执行一遍,适用于子查询本身成本很高的情况。
参考链接:
https://www.modb.pro/db/69161
http://www.postgres.cn/docs/12/queries-with.html
PostgreSQL CTE语句与materialized相关推荐
- 7.PostgreSQL操作语句
一.INSERT INTO 语句 PostgreSQL INSERT INTO 语句用于向表中插入新记录. 我们可以插入一行也可以同时插入多行. 1.1 语法 INSERT INTO 语句语法格式如下 ...
- 介绍PostgreSQL CTE(common table expressions)
介绍PostgreSQL CTE(common table expressions) 本文我们学习如何使用PostgreSQL CTE(common table expressions)简化复杂查询. ...
- mysql cte递归_SQLSERVER中CTE语句结构及CTE递归查询
SQL SERVER中CTE语句结构及CTE递归查询 CTE语句结构 公用表表达式 (CTE) 可以认为是在单个 SELECT.INSERT.UPDATE.DELETE 或 CREATE VIEW 语 ...
- Postgresql ALTER语句常用操作小结
postgresql版本:psql (9.3.4) 1.增加一列 复制代码代码如下: ALTER TABLE table_name ADD column_name datatype; ...
- PostgreSQL条件语句
PostgreSQL条件用于从数据库获取更具体的结果. 它们通常与WHERE子句一起使用. 具有子句的条件就像双层过滤器. 以下是PostgreSQL条件的列表: AND 条件 OR 条件 AND & ...
- postgresql copy语句
总述 copy命令用于在postgreSql表和标准文件系统直接传输数据. copy命令让PostgreSQL 服务器直接读写文件,因此文件必须位于服务器本地或能被直接访问. 该命令仅能在表上使用,不 ...
- PostgreSQL DELETE 语句
DELETE 语句 你可以使用 DELETE 语句来删除 highgodb 表中的数据. 语法 以下是 DELETE 语句删除数据的通用语法: DELETE FROM table_name WHERE ...
- PostgreSQL UPDATE 语句
UPDATE 语句 如果我们要更新在 highgodb 数据库中的数据,我们可以用 UPDATE 来操作. 语法 以下是 UPDATE 语句修改数据的通用 SQL 语法: UPDATE table_n ...
- postgreSQL 更新语句 关于字段不存在问题
常用的查询,更新或删除都有给表命名别名使用别名,但是在postgreSQL中,使用别名报字段不存在错误,需要直接使用对应的列名 错误 将set中引用的别名去除 UPDATE temp_product_ ...
最新文章
- vue ts 设置tslint提示_Typescript 在 Vue 中的实践(包含2.x、3.x)
- java client类_Jmeter中自定义JavaSamplerClient类的编写
- 二叉排序树(完整案例与完整C语言代码)
- css3 下边框缓缓划过_一篇文章带你了解CSS3按钮知识
- vs2017生成sqlserver 2017项目出现.Net SqlClient Data Provider: Msg 10343
- network reactnative_从零学React Native之14 网络请求
- c++中初始化列表顺序和声明顺序一致
- Xilinx FPGA单端时钟设计方法
- CSS遮罩层:hover状态丢失及解决方案
- paip.cpu占用高解决方案---ThreadMast 跟Process Lasso的使用
- SD卡格式化咋办?数据恢复看这里!
- 免费的二维码图片生成API接口和使用
- JHU计算机专业学费,约翰霍普金斯大学学费多少 贵不贵
- ajax的响应与取消响应
- 【转】优秀的JavaScript模块是怎样炼成的
- 计算机系统结构复习(五):ILP指令集并行
- Oracle11G的数据库数据导入导出(由11g上导出导入10g数据库等)
- Spring 学习笔记----->AOP
- 人工智能数学基础专栏目录
- python是一种面向____的高级语言_Python简介_语法_高薪Ptython系列专栏_2
热门文章
- PHP写动物世界,动物世界运动会(童话故事)
- 人生情长特别栏目《大姐的幸福》定制护肤还原肌肤本态
- 【王喆-推荐系统】线上服务篇-(task4)局部敏感哈希
- 【pipenv】 快速入门,超全面的pipenv教程!(教你如何快速创建python虚拟环境!)
- top和ps取长补短续篇3之进程定位
- Android 源码编译 及 mk文件解读
- 提交MapReduce任务出错:unknown queue: default
- 阀门制造工艺对阀门设计提出的工艺性
- 计算机总是提示网络电缆没有插,插入网络电缆后,如果台式计算机未连接到Internet,该怎么办...
- 数组循环对比删除数据