分区修剪

如果查询谓词指定了分区表达式,则查询优化器会根据已分区数据的 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;