分区修剪
如果查询谓词指定了分区表达式,则查询优化器会根据已分区数据的 ROS 容器计算谓词。每个 ROS 容器维护其分区键数据的最小值和最大值。查询优化器使用此元数据来确定执行查询所需的 ROS 容器,并从查询计划中省略或修剪其余容器。通过最大限度地减少它必须扫描的 ROS 容器的数量,查询优化器可以更快地执行查询。
例如,表可能按年份进行分区,如下所示:
=> CREATE TABLE ... PARTITION BY EXTRACT(year FROM date);
给定此表定义,其投影数据根据年份划分到 ROS 容器中,每个年份一个容器,在本例中为 2007 年、2008 年、2009 年。
以下查询指定分区表达式 date
:
=> SELECT ... WHERE date = '12-2-2009';
给定此查询,包含 2007 年和 2008 年数据的 ROS 容器不在所请求年份(2009 年)的范围内。在查询执行之前,查询优化器会从查询计划中修剪这些容器:
示例
假定表按时间分区,并且它将使用按时间限制数据的查询。
=> CREATE TABLE time ( tdate DATE NOT NULL, tnum INTEGER)
PARTITION BY EXTRACT(year FROM tdate);
=> CREATE PROJECTION time_p (tdate, tnum) AS
=> SELECT * FROM time ORDER BY tdate, tnum UNSEGMENTED ALL NODES;
注意
投影排序顺序不会影响分区修剪。=> INSERT INTO time VALUES ('03/15/04' , 1);
=> INSERT INTO time VALUES ('03/15/05' , 2);
=> INSERT INTO time VALUES ('03/15/06' , 3);
=> INSERT INTO time VALUES ('03/15/06' , 4);
在前面的一系列命令中插入的数据将加载到三个 ROS 容器(每个年份一个容器),因为这就是数据的分区方式:
=> SELECT * FROM time ORDER BY tnum;
tdate | tnum
------------+------
2004-03-15 | 1 --ROS1 (min 03/01/04, max 03/15/04)
2005-03-15 | 2 --ROS2 (min 03/15/05, max 03/15/05)
2006-03-15 | 3 --ROS3 (min 03/15/06, max 03/15/06)
2006-03-15 | 4 --ROS3 (min 03/15/06, max 03/15/06)
(4 rows)
当查询 time
表时,将发生以下操作:
-
在此查询中,Vertica 可以省略 ROS2 容器,因为它仅查找 2004 年:
=> SELECT COUNT(*) FROM time WHERE tdate = '05/07/2004';
-
在下一个查询中,Vertica 可以省略两个容器 ROS1 和 ROS3:
=> SELECT COUNT(*) FROM time WHERE tdate = '10/07/2005';
-
以下查询有一个针对
tnum
列的附加谓词,且该列中没有保留最小/最大值。此外,由于不支持使用逻辑运算符 OR,因此没有消除 ROS:=> SELECT COUNT(*) FROM time WHERE tdate = '05/07/2004' OR tnum = 7;