PostgreSQL 11 preview 分区过滤控制参数 - enable_partition_pruning

标签

PostgreSQL , 分区控制 , enable_partition_pruning


背景

PostgreSQL 10开始支持了分区表的语法,可以通过新的语法创建分区表,而更早的版本则需要使用inherit+check约束+rule/trigger来创建分区表。

《分区表锁粒度差异 - pg_pathman VS native partition table》

《PostgreSQL 传统 hash 分区方法和性能》

以往,PG通过constraint_exclusion参数来控制select,update,delete的选择。(作用于表、继承、分区表、UNION ALL等,根据设定决定要判断哪些表的check约束)

https://www.postgresql.org/docs/10/static/runtime-config-query.html#RUNTIME-CONFIG-QUERY-OTHER

分区较多时,constraint_exclusion控制,性能可能较差。

PG 11增加了一个参数 enable_partition_pruning ,仅用于控制分区表(不用于控制inherit, union all等操作)的QUERY。

也就是说,以后使用创建分区表的语法创建的表,必须通过enable_partition_pruning参数来控制,是否要对select,update,delete操作过滤到目标分区。

Add GUC enable_partition_pruning  
  
This controls both plan-time and execution-time new-style partition  
pruning.  While finer-grain control is possible (maybe using an enum GUC  
instead of boolean), there doesn't seem to be much need for that.  
  
This new parameter controls partition pruning for all queries:  
trivially, SELECT queries that affect partitioned tables are naturally  
under its control since they are using the new technology.  However,  
while UPDATE/DELETE queries do not use the new code, we make the new GUC  
control their behavior also (stealing control from  
constraint_exclusion), because it is more natural, and it leads to a  
more natural transition to the future in which those queries will also  
use the new pruning code.  
  
Constraint exclusion still controls pruning for regular inheritance  
situations (those not involving partitioned tables).  
  
Author: David Rowley  
Review: Amit Langote, Ashutosh Bapat, Justin Pryzby, David G. Johnston  
Discussion: https://postgr.es/m/CAKJS1f_0HwsxJG9m+nzU+CizxSdGtfe6iF_ykPYBiYft302DCw@mail.gmail.com  

test case

+--  
+-- Ensure the enable_partition_prune GUC properly disables partition pruning.  
+--  
+create table pp_lp (a int, value int) partition by list (a);  
+create table pp_lp1 partition of pp_lp for values in(1);  
+create table pp_lp2 partition of pp_lp for values in(2);  
+explain (costs off) select * from pp_lp where a = 1;  
+        QUERY PLAN          
+--------------------------  
+ Append  
+   ->  Seq Scan on pp_lp1  
+         Filter: (a = 1)  
+(3 rows)  
+  
+explain (costs off) update pp_lp set value = 10 where a = 1;  
+        QUERY PLAN          
+--------------------------  
+ Update on pp_lp  
+   Update on pp_lp1  
+   ->  Seq Scan on pp_lp1  
+         Filter: (a = 1)  
+(4 rows)  
+  
+explain (costs off) delete from pp_lp where a = 1;  
+        QUERY PLAN          
+--------------------------  
+ Delete on pp_lp  
+   Delete on pp_lp1  
+   ->  Seq Scan on pp_lp1  
+         Filter: (a = 1)  
+(4 rows)  
+set enable_partition_pruning = off;  
+set constraint_exclusion = 'partition'; -- this should not affect the result.  
+explain (costs off) select * from pp_lp where a = 1;  
+        QUERY PLAN          
+--------------------------  
+ Append  
+   ->  Seq Scan on pp_lp1  
+         Filter: (a = 1)  
+   ->  Seq Scan on pp_lp2  
+         Filter: (a = 1)  
+(5 rows)  
+  
+explain (costs off) update pp_lp set value = 10 where a = 1;  
+        QUERY PLAN          
+--------------------------  
+ Update on pp_lp  
+   Update on pp_lp1  
+   Update on pp_lp2  
+   ->  Seq Scan on pp_lp1  
+         Filter: (a = 1)  
+   ->  Seq Scan on pp_lp2  
+         Filter: (a = 1)  
+(7 rows)  
+  
+explain (costs off) delete from pp_lp where a = 1;  
+        QUERY PLAN          
+--------------------------  
+ Delete on pp_lp  
+   Delete on pp_lp1  
+   Delete on pp_lp2  
+   ->  Seq Scan on pp_lp1  
+         Filter: (a = 1)  
+   ->  Seq Scan on pp_lp2  
+         Filter: (a = 1)  
+(7 rows)  
+set constraint_exclusion = 'off'; -- this should not affect the result.  
+explain (costs off) select * from pp_lp where a = 1;  
+        QUERY PLAN          
+--------------------------  
+ Append  
+   ->  Seq Scan on pp_lp1  
+         Filter: (a = 1)  
+   ->  Seq Scan on pp_lp2  
+         Filter: (a = 1)  
+(5 rows)  
+  
+explain (costs off) update pp_lp set value = 10 where a = 1;  
+        QUERY PLAN          
+--------------------------  
+ Update on pp_lp  
+   Update on pp_lp1  
+   Update on pp_lp2  
+   ->  Seq Scan on pp_lp1  
+         Filter: (a = 1)  
+   ->  Seq Scan on pp_lp2  
+         Filter: (a = 1)  
+(7 rows)  
+  
+explain (costs off) delete from pp_lp where a = 1;  
+        QUERY PLAN          
+--------------------------  
+ Delete on pp_lp  
+   Delete on pp_lp1  
+   Delete on pp_lp2  
+   ->  Seq Scan on pp_lp1  
+         Filter: (a = 1)  
+   ->  Seq Scan on pp_lp2  
+         Filter: (a = 1)  
+(7 rows)  
+drop table pp_lp;  
+-- Ensure enable_partition_prune does not affect non-partitioned tables.  
+create table inh_lp (a int, value int);  
+create table inh_lp1 (a int, value int, check(a = 1)) inherits (inh_lp);  
+NOTICE:  merging column "a" with inherited definition  
+NOTICE:  merging column "value" with inherited definition  
+create table inh_lp2 (a int, value int, check(a = 2)) inherits (inh_lp);  
+NOTICE:  merging column "a" with inherited definition  
+NOTICE:  merging column "value" with inherited definition  
+set constraint_exclusion = 'partition';  
+-- inh_lp2 should be removed in the following 3 cases.  
+explain (costs off) select * from inh_lp where a = 1;  
+        QUERY PLAN           
+---------------------------  
+ Append  
+   ->  Seq Scan on inh_lp  
+         Filter: (a = 1)  
+   ->  Seq Scan on inh_lp1  
+         Filter: (a = 1)  
+(5 rows)  
+  
+explain (costs off) update inh_lp set value = 10 where a = 1;  
+        QUERY PLAN           
+---------------------------  
+ Update on inh_lp  
+   Update on inh_lp  
+   Update on inh_lp1  
+   ->  Seq Scan on inh_lp  
+         Filter: (a = 1)  
+   ->  Seq Scan on inh_lp1  
+         Filter: (a = 1)  
+(7 rows)  
+  
+explain (costs off) delete from inh_lp where a = 1;  
+        QUERY PLAN           
+---------------------------  
+ Delete on inh_lp  
+   Delete on inh_lp  
+   Delete on inh_lp1  
+   ->  Seq Scan on inh_lp  
+         Filter: (a = 1)  
+   ->  Seq Scan on inh_lp1  
+         Filter: (a = 1)  
+(7 rows)  
+-- Ensure we don't exclude normal relations when we only expect to exclude  
+-- inheritance children  
直接操作子表,不起作用constraint_exclusion = 'partition', on则起作用  
+explain (costs off) update inh_lp1 set value = 10 where a = 2;  
+        QUERY PLAN           
+---------------------------  
+ Update on inh_lp1  
+   ->  Seq Scan on inh_lp1  
+         Filter: (a = 2)  
+(3 rows)  
+  
  
直接操作子表,不起作用constraint_exclusion = 'partition', on则起作用  
postgres=# set constraint_exclusion = 'on';  
SET  
postgres=# explain (costs off) update inh_lp1 set value = 10 where a = 2;  
           QUERY PLAN             
--------------------------------  
 Update on inh_lp1  
   ->  Result  
         One-Time Filter: false  
(3 rows)  
  
+\set VERBOSITY terse   \\ -- suppress cascade details  
+drop table inh_lp cascade;  
+NOTICE:  drop cascades to 2 other objects  
+\set VERBOSITY default  
+reset enable_partition_pruning;  
+reset constraint_exclusion;  

参考

https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=055fb8d33da6ff9003e3da4b9944bdcd2e2b2a49

`pg_similarity` 是 PostgreSQL 中的一个扩展模块,它提供了用于文本相似度计算的工具。`pg_similarity_1_0` 版本可能指的是某个特定版本或旧版本的这个模块。在 PostgreSQL 中安装扩展,通常需要通过数据库管理系统来进行。 **安装步骤**(假设您使用的是 PostgreSQL 9.6及以上版本): 1. **确保已更新到最新版本**:首先检查您的 PostgreSQL 是否是最新的,因为有些旧版本可能不包含 pg_similarity。运行 `SELECT version();` 确认。 2. **备份数据库**:在进行任何操作之前,建议先备份您的数据库以防数据丢失。 3. **下载扩展文件**:访问 PostgreSQL 的官方扩展仓库 (https://www.postgresql.org/ftp/source/) 或者从第三方源下载 pg_similarity 的 .sql 文件,如 1_0 版本。 4. **解压扩展文件**:将下载的 .sql 文件解压到一个临时目录。 5. **加载扩展**:在 PostgreSQL 命令行中,使用 `\c your_database_name;` 切换到目标数据库,然后运行: ``` CREATE EXTENSION IF NOT EXISTS pg_similarity_1_0; ``` 如果扩展已存在,此命令会检查并确保为最新版本。 6. **验证安装**:可以通过查询系统信息表确认 pg_similarity 是否已成功安装: ``` SELECT * FROM pg_available_extensions WHERE name = 'pg_similarity'; ``` **相关问题--:** 1. PostgreSQL的其他扩展如何管理? 2. 如何在PostgreSQL中查看和管理现有的扩展? 3. pg_similarity是否支持自定义相似度算法?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值