分区裁剪

数据库可以识别出对象的子分区表。进而根据分区情况优化SQL语句,标识出需要存取的子分区表,不会存取不必要的子分区表(即裁剪)。也可以这样理解,分区裁剪就是在查询中跳过不必存储的子分区表。

对于每个SQL语句,数据库能够根据用户设定的查询条件,避免访问不需要的子分区表。例如,一个查询只需要三月份的销售数据,就不必获取其余十一个月的数据。这种智能裁剪技术能够显著地减少数据访问量,从而大幅度提升查询性能。

如果优化器在裁剪过程中确定某些子分区表中的全部数据与某些查询条件相对应,它在评估时将谓项列表(即WHERE子句)中移除这些查询条件,从而提升语句的执行性能。但是如果用户在SQL语句中的分区键上使用了函数(TO_DATE除外),优化器将无法对相关分区进行裁剪。与此类似的是,如果用户在SQL语句中的索引键上使用了函数(函数索引除外),优化器也将无法使用相关的索引。

如果表及其上的索引依据不同列进行水平分区,在查询器优化查询时即使不能对表分区进行裁剪,也可以对索引分区进行裁剪。用户创建分区索引后,就能有效减少SQL语句所需存储的数据量,从而提升在大数量表上执行操作的性能。

对于相等、范围、LIKE及IN-列表等谓词可以考虑通过范围分区或列表分区来实现分区裁剪;对于相等、IN-列表等谓词还可以通过哈希分区来实现分区裁剪。

示例:分区裁剪

--  清理环境
DROP TABLE tab;

-- 创建分区表
CREATE TABLE tab(C1 INT)
PARTITION BY RANGE(C1)
(
    PARTITION P1 VALUES LESS THAN(100),
    PARTITION P2 VALUES LESS THAN(1000)
);

INSERT INTO tab VALUES(10);
INSERT INTO tab VALUES(50);
INSERT INTO tab VALUES(200);
INSERT INTO tab VALUES(400);


EXPLAIN ANALYZE SELECT * FROM tab WHERE c1 < 250;
QUERY PLAN(text)      
----------------------
Partition Seq Scan on TAB(1..2)  (cost=0.00..110.40 rows=2731 width=4) (actual time=0.02..0.04 rows=3 loops=1)
  Scan Key: (C1 < 250)
Planning Time: 0.17 msec
Execution Time: 0.10 msec
总数目:4


EXPLAIN ANALYZE SELECT * FROM tab WHERE c1 = 200;
QUERY PLAN(text)      
----------------------
Partition Seq Scan on TAB(2)  (cost=0.00..110.40 rows=41 width=4) (actual time=0.01..0.02 rows=1 loops=1)
  Scan Key: (C1 = 200)
Planning Time: 0.10 msec
Execution Time: 0.05 msec
总数目:4


EXPLAIN ANALYZE SELECT * FROM tab WHERE c1 = 200 or c1 = 10;
QUERY PLAN(text)      
----------------------
Partition Seq Scan on TAB(1..2)  (cost=0.00..130.88 rows=82 width=4) (actual time=0.02..0.04 rows=2 loops=1)
  Scan Filter: ((C1 = 200) OR (C1 = 10))
Planning Time: 0.88 msec
Execution Time: 0.08 msec
总数目:4


EXPLAIN ANALYZE SELECT * FROM tab partition(p1);
QUERY PLAN(text)      
----------------------
Partition Seq Scan on TAB(1)  (cost=0.00..89.92 rows=8192 width=4) (actual time=0.01..0.02 rows=2 loops=1)
Planning Time: 0.06 msec
Execution Time: 0.04 msec
总数目:3