分区剪枝是指对于分区表或分区索引来说,优化器可以自动从FROM和WHERE字句里根据分区键提取出需要扫描的分区,从而避免全表扫描,减少扫描的数据块,提高性能。
分区剪枝机制使用下面两个剪枝方式,这两种方式仅对您要搜索的值可能所属的分区限制了数据的搜索。这两种剪枝方式都能从查询执行计划中删除分区,从而提高性能:
- 排除约束
- 快速剪枝
排除约束
参数constraint_exclusion用于控制排除约束。它有on、off 或partition这三种值的其中一个。要启用排除约束,就必须将参数constraint_exclusion设为partition或on。通过缺省设置,将参数设为partition。
当您启用了排除约束,服务器就会检查定义给每个分区的约束来决定分区是否能满足查询。
当您执行一条不包含WHERE子句的SELECT语句时,查询计划器必须推荐一个用于搜索整个表的执行计划。当您执行一条包含WHERE子句的SELECT语句时,查询计划器就会决定要存储记录的分区,并发送查询碎片给这个分区,然后从执行计划中剪去不能包含记录的分区。如果您不使用分区表,那么禁用排除约束可能会提高性能。
快速剪枝
和排除约束技巧一样,快速剪枝的技巧只能对包括WHERE(或连接)子句的查询,且只有当WHERE子句中的限定符与某种格式匹配时进行优化。这两种情况下,查询计划器将会避免搜索那些可能不包含所要查询的数据分区中的数据。
快速剪枝技巧由布林配置参数polardb partition pruning控制。如果布林配置参数polardb partition pruning为ON,那么PolarDB将会快速剪去某些特定的查询。如果布林配置参数polardb partition pruning为OFF,那么PolarDB就不会启用快速剪枝技巧。
需要注意的是:快速剪枝技巧不能优化对子分区表的查询,或分区于多个列上的范围分区表的查询。
CREATE TABLE sales_hist(..., country text, ...)
PARTITION BY LIST(country) (
PARTITION americas VALUES('US', 'CA', 'MX'),
PARTITION europe VALUES('BE', 'NL', 'FR'),
PARTITION asia VALUES('JP', 'PK', 'CN'),
PARTITION others VALUES(DEFAULT)
)
WHERE country = 'US' WHERE country IS NULL;
指定第一个WHERE子句, 快速剪枝技巧就会删除分区europe、 asia 及 others。因为这些分区不能存储满足限定符WHERE country = 'US'
的记录。 指定第二个WHERE子句, 快速剪枝就会删除分区americas、 europe 及asia。因为这些分区不能在country IS NULL时存储记录。 在WHERE子句中指定的运算符必须是一个等号(=)或是一个适于分区列数据类型的相同运算符。
对于范围分区表来说,PolarDB能快速剪去包含WHERE子句(用于约束分区列到文本值)的查询,但运算符可能是大于(>)、大于等于(>=)、小于(<)、小于等于(<=)中的任何一种。
WHERE size > 100 AND size <= 200 WHERE size BETWEEN 100 AND 200
CREATE TABLE boxes(id int, size int, color text)
PARTITION BY RANGE(size)
(
PARTITION small VALUES LESS THAN(100),
PARTITION medium VALUES LESS THAN(200),
PARTITION large VALUES LESS THAN(300)
)
WHERE size > 100 -- scan partitions 'medium' and 'large'
WHERE size >= 100 -- scan partitions 'medium' and 'large'
WHERE size = 100 -- scan partition 'medium'
WHERE size <= 100 -- scan partitions 'small' and 'medium'
WHERE size < 100 -- scan partition 'small'
WHERE size > 100 AND size < 199 -- scan partition 'medium'
WHERE size BETWEEN 100 AND 199 -- scan partition 'medium'
WHERE color = 'red' AND size = 100 -- scan 'medium'
WHERE color = 'red' AND (size > 100 AND size < 199) -- scan 'medium'
在每一种情况下,快速剪枝技巧都要求限定符指的必须是分区列和文本值(或IS NULL/IS NOT NULL)。 需要注意的是,快速剪枝同样也能优化包含上述格式的WHERE子句的DELETE和UPDATE语句。
区别
快速剪枝与排除约束这两种方式的区别在于,快速剪枝方式可了解分区表中各分区之间的关系,而排除约束技巧却不具备这个特性。
例如,当查询在列表分区表中搜索一个具体的值时,快速剪枝技巧能推理出只有一个具体的分区才会有这个值,但排除约束技巧则必须要检查定义给每个分区的约束。快速剪枝技巧在计划过程中出现的较早,从而减少计划器必须考虑的分区数量,但排除约束则在计划过程中出现的较晚。