关于PostgreSQL的分区表的历史及分区裁剪参数enable_partition_pruning与constraint_exclusion的区别

本文主要是介绍关于PostgreSQL的分区表的历史及分区裁剪参数enable_partition_pruning与constraint_exclusion的区别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 疑惑

我们知道控制分区裁剪的参数有两个:

  • enable_partition_pruning
  • constraint_exclusion

这两个参数有什么区别呢?

2. 解答

要说明这两个参数的区别需要先讲一讲PostgreSQL数据库中分区的历史,在PostgreSQL 10版本之前,PostgreSQL数据库实际上是没有单独的创建分区表的DDL语句,都是通过表继承的原理来创建分区表,这样使得在PostgreSQL中使用分区表不是很方便,到PostgreSQL 10之后,PostgreSQL扩展了创建表的DDL语句,可以用这个DDL语句来创建分区表,原先使用继承的方式还是可以创建分区表,但这两种分区表是不能混用的。于是PostgreSQL 10增加的分区表叫声明式分区(Declarative Partitioning),原先使用表继承的方式仍然可以实现分区表的功能。

而使用继承的方式实现的分区表的分区裁剪是靠设置参数“constraint_exclusion=partition”来实现的,而如果使用了声明式分区表,则需要使用参数“enable_partition_pruning”来控制是否使用分区裁剪功能。

3. 测试

创建声明式分区表:

 
  1. CREATE TABLE ptab01 (
  2. id int not null,
  3. tm timestamptz not null
  4. ) PARTITION BY RANGE (tm);
  5. create table ptab01_202001 partition of ptab01 for values from ('2020-01-01') to ('2020-02-01');
  6. create table ptab01_202002 partition of ptab01 for values from ('2020-02-01') to ('2020-03-01');
  7. create table ptab01_202003 partition of ptab01 for values from ('2020-03-01') to ('2020-04-01');
  8. create table ptab01_202004 partition of ptab01 for values from ('2020-04-01') to ('2020-05-01');
  9. create table ptab01_202005 partition of ptab01 for values from ('2020-05-01') to ('2020-06-01');
  10. insert into ptab01 select extract(epoch from seq), seq from generate_series('2020-01-01'::timestamptz, '2020-05-31 23:59:59'::timestamptz, interval '10 seconds') as seq;

创建传统的继承式的分区表:

 
  1. CREATE TABLE ptab02 (
  2. id int not null,
  3. tm timestamptz not null
  4. );
  5. CREATE TABLE ptab02_202001 (
  6. CHECK ( tm >= '2020-01-01'::timestamptz AND tm < '2020-02-01'::timestamptz )
  7. ) INHERITS (ptab02);
  8. CREATE TABLE ptab02_202002 (
  9. CHECK ( tm >= '2020-02-01'::timestamptz AND tm < '2020-03-01'::timestamptz )
  10. ) INHERITS (ptab02);
  11. CREATE TABLE ptab02_202003 (
  12. CHECK ( tm >= '2020-03-01'::timestamptz AND tm < '2020-04-01'::timestamptz )
  13. ) INHERITS (ptab02);
  14. CREATE TABLE ptab02_202004 (
  15. CHECK ( tm >= '2020-04-01'::timestamptz AND tm < '2020-05-01'::timestamptz )
  16. ) INHERITS (ptab02);
  17. CREATE TABLE ptab02_202005 (
  18. CHECK ( tm >= '2020-05-01'::timestamptz AND tm < '2020-06-01'::timestamptz )
  19. ) INHERITS (ptab02);
  20. CREATE OR REPLACE FUNCTION ptab02_insert_trigger()
  21. RETURNS TRIGGER AS $$
  22. BEGIN
  23. IF NEW.tm >= '2020-01-01'::timestamptz AND NEW.tm < '2020-02-01'::timestamptz THEN
  24. INSERT INTO ptab02_202001 VALUES (NEW.*);
  25. ELSIF NEW.tm >= '2020-02-01'::timestamptz AND NEW.tm < '2020-03-01'::timestamptz THEN
  26. INSERT INTO ptab02_202002 VALUES (NEW.*);
  27. ELSIF NEW.tm >= '2020-02-01'::timestamptz AND NEW.tm < '2020-04-01'::timestamptz THEN
  28. INSERT INTO ptab02_202003 VALUES (NEW.*);
  29. ELSIF NEW.tm >= '2020-02-01'::timestamptz AND NEW.tm < '2020-05-01'::timestamptz THEN
  30. INSERT INTO ptab02_202004 VALUES (NEW.*);
  31. ELSIF NEW.tm >= '2020-02-01'::timestamptz AND NEW.tm < '2020-06-01'::timestamptz THEN
  32. INSERT INTO ptab02_202005 VALUES (NEW.*);
  33. ELSE
  34. RAISE 'value % out of range ', NEW.tm;
  35. END IF;
  36. RETURN NULL;
  37. END;
  38. $$
  39. LANGUAGE plpgsql;
  40. CREATE TRIGGER insert_ptab02_trigger
  41. BEFORE INSERT ON ptab02
  42. FOR EACH ROW EXECUTE FUNCTION ptab02_insert_trigger();
  43. insert into ptab02 select extract(epoch from seq), seq from generate_series('2020-01-01'::timestamptz, '2020-05-31 23:59:59'::timestamptz, interval '10 seconds') as seq;

默认情况下constraint_exclusion为partition和enable_partition_pruning为on,不管是表继承方式实现的分区表还是声明式分区表都可以走到分区裁剪,如下所示:

 
  1. postgres=# show constraint_exclusion;
  2. constraint_exclusion
  3. ----------------------
  4. partition
  5. (1 row)
  6. postgres=# show enable_partition_pruning;
  7. enable_partition_pruning
  8. --------------------------
  9. on
  10. (1 row)
  11. postgres=# explain select * from ptab01 where tm='2020-01-07'::timestamptz;
  12. QUERY PLAN
  13. ---------------------------------------------------------------------------------------
  14. Gather (cost=1000.00..4417.51 rows=1 width=12)
  15. Workers Planned: 1
  16. -> Parallel Seq Scan on ptab01_202001 ptab01 (cost=0.00..3417.41 rows=1 width=12)
  17. Filter: (tm = '2020-01-07 00:00:00+08'::timestamp with time zone)
  18. (4 rows)
  19. postgres=# explain select * from ptab02 where tm='2020-01-07'::timestamptz;
  20. QUERY PLAN
  21. -----------------------------------------------------------------------------------------------
  22. Gather (cost=1000.00..4417.62 rows=2 width=12)
  23. Workers Planned: 2
  24. -> Parallel Append (cost=0.00..3417.42 rows=2 width=12)
  25. -> Parallel Seq Scan on ptab02_202001 ptab02_2 (cost=0.00..3417.41 rows=1 width=12)
  26. Filter: (tm = '2020-01-07 00:00:00+08'::timestamp with time zone)
  27. -> Parallel Seq Scan on ptab02 ptab02_1 (cost=0.00..0.00 rows=1 width=12)
  28. Filter: (tm = '2020-01-07 00:00:00+08'::timestamp with time zone)
  29. (7 rows)

从上面可以看出,声明式分区表只扫描了包括指定时间实际的分区ptab01_202001,没有扫描其他时间段的分区,继承式的分区表只扫描了父表ptab02和包括指定时间实际的分区ptab02_202001。

当我们把参数enable_partition_pruning设置为off,这是可以看到查询声明式分区表时,会扫描所有分区,没有进行分区裁剪,但是继承式分区表还是进行了分区裁剪:

 
  1. postgres=# set enable_partition_pruning to off;
  2. SET
  3. postgres=# explain select * from ptab01 where tm='2020-01-07'::timestamptz;
  4. QUERY PLAN
  5. -----------------------------------------------------------------------------------------------
  6. Gather (cost=1000.00..17758.00 rows=5 width=12)
  7. Workers Planned: 2
  8. -> Parallel Append (cost=0.00..16757.50 rows=5 width=12)
  9. -> Parallel Seq Scan on ptab01_202001 ptab01_1 (cost=0.00..3417.41 rows=1 width=12)
  10. Filter: (tm = '2020-01-07 00:00:00+08'::timestamp with time zone)
  11. -> Parallel Seq Scan on ptab01_202003 ptab01_3 (cost=0.00..3417.41 rows=1 width=12)
  12. Filter: (tm = '2020-01-07 00:00:00+08'::timestamp with time zone)
  13. -> Parallel Seq Scan on ptab01_202005 ptab01_5 (cost=0.00..3417.41 rows=1 width=12)
  14. Filter: (tm = '2020-01-07 00:00:00+08'::timestamp with time zone)
  15. -> Parallel Seq Scan on ptab01_202004 ptab01_4 (cost=0.00..3307.88 rows=1 width=12)
  16. Filter: (tm = '2020-01-07 00:00:00+08'::timestamp with time zone)
  17. -> Parallel Seq Scan on ptab01_202002 ptab01_2 (cost=0.00..3197.35 rows=1 width=12)
  18. Filter: (tm = '2020-01-07 00:00:00+08'::timestamp with time zone)
  19. (13 rows)
  20. postgres=# explain select * from ptab02 where tm='2020-01-07'::timestamptz;
  21. QUERY PLAN
  22. -----------------------------------------------------------------------------------------------
  23. Gather (cost=1000.00..4417.62 rows=2 width=12)
  24. Workers Planned: 2
  25. -> Parallel Append (cost=0.00..3417.42 rows=2 width=12)
  26. -> Parallel Seq Scan on ptab02_202001 ptab02_2 (cost=0.00..3417.41 rows=1 width=12)
  27. Filter: (tm = '2020-01-07 00:00:00+08'::timestamp with time zone)
  28. -> Parallel Seq Scan on ptab02 ptab02_1 (cost=0.00..0.00 rows=1 width=12)
  29. Filter: (tm = '2020-01-07 00:00:00+08'::timestamp with time zone)
  30. (7 rows)

当我们把参数constraint_exclusion设置为off,这是可以看到继承式分区表就没有再做分区裁剪了:

 
  1. postgres=# set constraint_exclusion to off;
  2. SET
  3. postgres=# explain select * from ptab02 where tm='2020-01-07'::timestamptz;
  4. QUERY PLAN
  5. -----------------------------------------------------------------------------------------------
  6. Gather (cost=1000.00..17758.10 rows=6 width=12)
  7. Workers Planned: 2
  8. -> Parallel Append (cost=0.00..16757.50 rows=6 width=12)
  9. -> Parallel Seq Scan on ptab02_202001 ptab02_2 (cost=0.00..3417.41 rows=1 width=12)
  10. Filter: (tm = '2020-01-07 00:00:00+08'::timestamp with time zone)
  11. -> Parallel Seq Scan on ptab02_202003 ptab02_4 (cost=0.00..3417.41 rows=1 width=12)
  12. Filter: (tm = '2020-01-07 00:00:00+08'::timestamp with time zone)
  13. -> Parallel Seq Scan on ptab02_202005 ptab02_6 (cost=0.00..3417.41 rows=1 width=12)
  14. Filter: (tm = '2020-01-07 00:00:00+08'::timestamp with time zone)
  15. -> Parallel Seq Scan on ptab02_202004 ptab02_5 (cost=0.00..3307.88 rows=1 width=12)
  16. Filter: (tm = '2020-01-07 00:00:00+08'::timestamp with time zone)
  17. -> Parallel Seq Scan on ptab02_202002 ptab02_3 (cost=0.00..3197.35 rows=1 width=12)
  18. Filter: (tm = '2020-01-07 00:00:00+08'::timestamp with time zone)
  19. -> Parallel Seq Scan on ptab02 ptab02_1 (cost=0.00..0.00 rows=1 width=12)
  20. Filter: (tm = '2020-01-07 00:00:00+08'::timestamp with time zone)
  21. (15 rows)

由此可见:

  • enable_partition_pruning:只控制声明式分区表的分区裁剪,对继承式分区表没有影响。
  • constraint_exclusion:只控制继承式分区表的分区裁剪,对声明式分区表没有影响。

4. 区别

通常声明式分区比继承式分区表在更多的情况下能走到分区裁剪,如在select * from tab01 where tm = (select tm from tab02);类似的SQL中:

 
  1. postgres=# explain analyze select * from ptab01 where tm = (select tm from tabtm);
  2. QUERY PLAN
  3. ------------------------------------------------------------------------------------------------------------------------------------------
  4. Gather (cost=1001.01..17759.01 rows=5 width=12) (actual time=4.154..27.762 rows=1 loops=1)
  5. Workers Planned: 2
  6. Params Evaluated: $0
  7. Workers Launched: 2
  8. InitPlan 1 (returns $0)
  9. -> Seq Scan on tabtm (cost=0.00..1.01 rows=1 width=8) (actual time=0.008..0.009 rows=1 loops=1)
  10. -> Parallel Append (cost=0.00..16757.50 rows=5 width=12) (actual time=1.228..6.338 rows=0 loops=3)
  11. -> Parallel Seq Scan on ptab01_202001 ptab01_1 (cost=0.00..3417.41 rows=1 width=12) (actual time=3.652..18.978 rows=1 loops=1)
  12. Filter: (tm = $0)
  13. Rows Removed by Filter: 267839
  14. -> Parallel Seq Scan on ptab01_202003 ptab01_3 (cost=0.00..3417.41 rows=1 width=12) (never executed)
  15. Filter: (tm = $0)
  16. -> Parallel Seq Scan on ptab01_202005 ptab01_5 (cost=0.00..3417.41 rows=1 width=12) (never executed)
  17. Filter: (tm = $0)
  18. -> Parallel Seq Scan on ptab01_202004 ptab01_4 (cost=0.00..3307.88 rows=1 width=12) (never executed)
  19. Filter: (tm = $0)
  20. -> Parallel Seq Scan on ptab01_202002 ptab01_2 (cost=0.00..3197.35 rows=1 width=12) (never executed)
  21. Filter: (tm = $0)
  22. Planning Time: 0.121 ms
  23. Execution Time: 27.858 ms
  24. (20 rows)
  25. postgres=# explain analyze select * from ptab02 where tm = (select tm from tabtm);
  26. QUERY PLAN
  27. -------------------------------------------------------------------------------------------------------------------------------------------
  28. Gather (cost=1001.01..17759.11 rows=6 width=12) (actual time=107.141..107.310 rows=1 loops=1)
  29. Workers Planned: 2
  30. Params Evaluated: $0
  31. Workers Launched: 2
  32. InitPlan 1 (returns $0)
  33. -> Seq Scan on tabtm (cost=0.00..1.01 rows=1 width=8) (actual time=0.005..0.006 rows=1 loops=1)
  34. -> Parallel Append (cost=0.00..16757.50 rows=6 width=12) (actual time=59.127..81.720 rows=0 loops=3)
  35. -> Parallel Seq Scan on ptab02_202001 ptab02_2 (cost=0.00..3417.41 rows=1 width=12) (actual time=5.747..39.632 rows=0 loops=2)
  36. Filter: (tm = $0)
  37. Rows Removed by Filter: 133920
  38. -> Parallel Seq Scan on ptab02_202003 ptab02_4 (cost=0.00..3417.41 rows=1 width=12) (actual time=45.304..45.304 rows=0 loops=1)
  39. Filter: (tm = $0)
  40. Rows Removed by Filter: 267840
  41. -> Parallel Seq Scan on ptab02_202005 ptab02_6 (cost=0.00..3417.41 rows=1 width=12) (actual time=21.245..21.245 rows=0 loops=2)
  42. Filter: (tm = $0)
  43. Rows Removed by Filter: 133920
  44. -> Parallel Seq Scan on ptab02_202004 ptab02_5 (cost=0.00..3307.88 rows=1 width=12) (actual time=60.385..60.385 rows=0 loops=1)
  45. Filter: (tm = $0)
  46. Rows Removed by Filter: 259200
  47. -> Parallel Seq Scan on ptab02_202002 ptab02_3 (cost=0.00..3197.35 rows=1 width=12) (actual time=17.671..17.671 rows=0 loops=1)
  48. Filter: (tm = $0)
  49. Rows Removed by Filter: 250560
  50. -> Parallel Seq Scan on ptab02 ptab02_1 (cost=0.00..0.00 rows=1 width=12) (actual time=0.000..0.001 rows=0 loops=1)
  51. Filter: (tm = $0)
  52. Planning Time: 0.171 ms
  53. Execution Time: 107.431 ms
  54. (26 rows)

从上面可以看到声明式分区可以做动态的分区裁剪,不需要扫描的分区后面会有“(never executed)”的提示,表示把这些分区表都跳过了。

这篇关于关于PostgreSQL的分区表的历史及分区裁剪参数enable_partition_pruning与constraint_exclusion的区别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1116245

相关文章

Andrej Karpathy最新采访:认知核心模型10亿参数就够了,AI会打破教育不公的僵局

夕小瑶科技说 原创  作者 | 海野 AI圈子的红人,AI大神Andrej Karpathy,曾是OpenAI联合创始人之一,特斯拉AI总监。上一次的动态是官宣创办一家名为 Eureka Labs 的人工智能+教育公司 ,宣布将长期致力于AI原生教育。 近日,Andrej Karpathy接受了No Priors(投资博客)的采访,与硅谷知名投资人 Sara Guo 和 Elad G

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

如何在页面调用utility bar并传递参数至lwc组件

1.在app的utility item中添加lwc组件: 2.调用utility bar api的方式有两种: 方法一,通过lwc调用: import {LightningElement,api ,wire } from 'lwc';import { publish, MessageContext } from 'lightning/messageService';import Ca

4B参数秒杀GPT-3.5:MiniCPM 3.0惊艳登场!

​ 面壁智能 在 AI 的世界里,总有那么几个时刻让人惊叹不已。面壁智能推出的 MiniCPM 3.0,这个仅有4B参数的"小钢炮",正在以惊人的实力挑战着 GPT-3.5 这个曾经的AI巨人。 MiniCPM 3.0 MiniCPM 3.0 MiniCPM 3.0 目前的主要功能有: 长上下文功能:原生支持 32k 上下文长度,性能完美。我们引入了

native和static native区别

本文基于Hello JNI  如有疑惑,请看之前几篇文章。 native 与 static native java中 public native String helloJni();public native static String helloJniStatic();1212 JNI中 JNIEXPORT jstring JNICALL Java_com_test_g

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出 在数字化时代,文本到语音(Text-to-Speech, TTS)技术已成为人机交互的关键桥梁,无论是为视障人士提供辅助阅读,还是为智能助手注入声音的灵魂,TTS 技术都扮演着至关重要的角色。从最初的拼接式方法到参数化技术,再到现今的深度学习解决方案,TTS 技术经历了一段长足的进步。这篇文章将带您穿越时

如何确定 Go 语言中 HTTP 连接池的最佳参数?

确定 Go 语言中 HTTP 连接池的最佳参数可以通过以下几种方式: 一、分析应用场景和需求 并发请求量: 确定应用程序在特定时间段内可能同时发起的 HTTP 请求数量。如果并发请求量很高,需要设置较大的连接池参数以满足需求。例如,对于一个高并发的 Web 服务,可能同时有数百个请求在处理,此时需要较大的连接池大小。可以通过压力测试工具模拟高并发场景,观察系统在不同并发请求下的性能表现,从而

Android fill_parent、match_parent、wrap_content三者的作用及区别

这三个属性都是用来适应视图的水平或者垂直大小,以视图的内容或尺寸为基础的布局,比精确的指定视图的范围更加方便。 1、fill_parent 设置一个视图的布局为fill_parent将强制性的使视图扩展至它父元素的大小 2、match_parent 和fill_parent一样,从字面上的意思match_parent更贴切一些,于是从2.2开始,两个属性都可以使用,但2.3版本以后的建议使

Collection List Set Map的区别和联系

Collection List Set Map的区别和联系 这些都代表了Java中的集合,这里主要从其元素是否有序,是否可重复来进行区别记忆,以便恰当地使用,当然还存在同步方面的差异,见上一篇相关文章。 有序否 允许元素重复否 Collection 否 是 List 是 是 Set AbstractSet 否

查看提交历史 —— Git 学习笔记 11

查看提交历史 查看提交历史 不带任何选项的git log-p选项--stat 选项--pretty=oneline选项--pretty=format选项git log常用选项列表参考资料 在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史。 完成这个任务最简单而又有效的 工具是 git log 命令。 接下来的例子会用一个用于演示的 simplegit