修整 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 BY
、ORDER BY
或HAVING
子句 -
DISTINCT
关键字 -
LIMIT
或OFFSET
子句 -
UNION
、EXCEPT
或INTERSECT
子句 -
EXISTS
子查询
示例
如果谓词适用于视图或子查询,只要在修整之前评估谓词,即可对修整操作进行优化。下面举两个示例。
视图修整
在本例中,视图 v1
定义如下:
=> CREATE VIEW v1 AS SELECT * FROM a;
以下查询指定此视图:
=> SELECT * FROM v1 JOIN b ON x=y WHERE x > 10;
在没有修整的情况下,优化器按如下方式评估查询:
-
评估子查询。
-
应用谓词
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;