修整 FROM 子句子查询

FROM 子句子查询的评估通常早于它们的包含查询。在某些情况下,优化器修整FROM子句查询,使查询可以更高效地执行。

例如,为了针对以下语句创建查询计划,Vertica 查询优化器会先评估表 t1 中的所有记录,然后再评估表 t0 中的记录:

=> SELECT * FROM (SELECT a, MAX(a) AS max FROM (SELECT * FROM t1) AS t0 GROUP BY a);

使用上述查询,优化器可以在内部修整它,如下所示:

=> SELECT * FROM (SELECT a, MAX(a) FROM t1 GROUP BY a) AS t0;

两个查询返回了相同的结果,但修整后的查询的运行速度更快。

修整视图

当查询的 FROM 子句指定视图时,优化器通过将视图替换为视图封装的查询来扩展视图。如果视图包含符合修整条件的子查询,则优化器会生成一个查询计划来修整这些子查询。

修整限制

如果子查询或视图包含以下元素之一,则优化器无法创建修整查询计划:

  • 聚合函数

  • 分析函数

  • 外联接(左外联接、右外联接或全外联接)

  • GROUP BYORDER BYHAVING 子句

  • DISTINCT 关键字

  • LIMITOFFSET 子句

  • UNIONEXCEPTINTERSECT 子句

  • EXISTS 子查询

示例

如果谓词适用于视图或子查询,只要在修整之前评估谓词,即可对修整操作进行优化。下面举两个示例。

视图修整

在本例中,视图 v1 定义如下:

=> CREATE VIEW v1 AS SELECT * FROM a;

以下查询指定此视图:

=> SELECT * FROM v1 JOIN b ON x=y WHERE x > 10;

在没有修整的情况下,优化器按如下方式评估查询:

  1. 评估子查询。

  2. 应用谓词 WHERE x > 10

相反,优化器可以通过在评估子查询之前应用谓词来创建修整查询计划。这减少了优化器的工作,因为它只将记录 WHERE x > 10 返回到包含查询。

Vertica 在内部转换了上述查询,如下所示:

=> SELECT * FROM (SELECT * FROM a) AS t1 JOIN b ON x=y WHERE x > 10;

然后,优化器修整查询:

=> SELECT * FROM a JOIN b ON x=y WHERE x > 10;

子查询修整

以下示例演示 Vertica 如何在 WHERE 子句 IN 子查询中转换 FROM 子句子查询。给定以下查询:

=> SELECT * FROM a
   WHERE b IN (SELECT b FROM (SELECT * FROM t2)) AS D WHERE x=1;

优化器将其修整如下:

=> SELECT * FROM a
   WHERE b IN (SELECT b FROM t2) AS D WHERE x=1;

另请参阅

子查询限制