WITH 子句的实体化
实体化启用之后,Vertica 会对每个 WITH 子句进行一次评估,将结果存储在临时表中,然后在查询需要时引用此表。主要查询执行完成之后,Vertica 会将临时表删除。
注意
如果主要查询返回了错误,仅当客户端会话结束之后才可能会删除临时表。如果 WITH 子句非常复杂,例如当 WITH 子句包含 JOIN 和 GROUP BY 子句,并且在主要查询中多次被引用时,实体化可帮助提高性能。
如果实体化已启用,WITH 语句会自动提交用户事务。即使将 EXPLAIN 与 WITH 语句一起使用,也是如此。
启用 WITH 子句实体化
WITH 实体化由配置参数 WithClauseMaterialization 设置,默认设置为 0(禁用)。您可以分别使用 ALTER DATABASE 和 ALTER SESSION,通过在数据库和会话级别设置 WithClauseMaterialization 来启用和禁用实体化:
-
数据库:
=> ALTER DATABASE db-spec SET PARAMETER WithClauseMaterialization={ 0 | 1 }; => ALTER DATABASE db-spec CLEAR PARAMETER WithClauseMaterialization;
-
会话:参数设置将继续有效,直到以显式方式清除它,或者会话结束。
=> ALTER SESSION SET PARAMETER WithClauseMaterialization={ 0 | 1 }; => ALTER SESSION CLEAR PARAMETER WithClauseMaterialization;
您还可以使用提示 ENABLE_WITH_CLAUSE_MATERIALIZATION 为单个查询启用 WITH 实体化。如果查询返回,则会自动清除实体化。例如:
=> WITH /*+ENABLE_WITH_CLAUSE_MATERIALIZATION */ revenue AS (
SELECT vendor_key, SUM(total_order_cost) AS total_revenue
FROM store.store_orders_fact
GROUP BY vendor_key ORDER BY 1)
...
使用 EE5 临时关系处理 WITH 子句
默认情况下,当重用 WITH 子句查询时,Vertica 将这些 WITH 子句查询输出保存在 EE5 临时关系中。不过,可以更改此选项。可以通过以下设置方式,使用配置参数 EnableWITHTempRelReuseLimit 来设置 EE5 临时关系支持:
-
0:禁用此功能。
-
1:将所有 WITH 子句查询强制保存到 EE5 临时关系中,无论它们是否被重用。
-
2(默认值):仅将重用的 WITH 子句查询保存到 EE5 临时关系中。
-
3 及 3 以上:仅当使用 WITH 子句查询至少达到此次数时才将其保存到 EE5 临时关系中。
可以分别使用 ALTER DATABASE 和 ALTER SESSION,在数据库和会话级别设置 EnableWITHTempRelReuseLimit。当 WithClauseMaterialization 设置为 1 时,该设置将覆盖任何 EnableWITHTempRelReuseLimit 设置。
请注意,对于具有复杂类型的 WITH 查询,禁用临时关系。
示例
以下示例显示适合用于实体化的 WITH 子句。查询获取在所有订单中拥有最高合并订单成本的供应商的数据:
-- Enable materialization
=> ALTER SESSION SET PARAMETER WithClauseMaterialization=1;
-- Define WITH clause
=> WITH revenue AS (
SELECT vendor_key, SUM(total_order_cost) AS total_revenue
FROM store.store_orders_fact
GROUP BY vendor_key ORDER BY 1)
-- End WITH clause
-- Primary query
=> SELECT vendor_name, vendor_address, vendor_city, total_revenue
FROM vendor_dimension v, revenue r
WHERE v.vendor_key = r.vendor_key AND total_revenue = (SELECT MAX(total_revenue) FROM revenue )
ORDER BY vendor_name;
vendor_name | vendor_address | vendor_city | total_revenue
------------------+----------------+-------------+---------------
Frozen Suppliers | 471 Mission St | Peoria | 49877044
(1 row)
Vertica 按以下方式处理此查询:
-
WITH 子句
revenue
通过store.store_orders_fact
表评估 SELECT 语句。 -
revenue
子句的结果存储在本地临时表中。 -
无论何时引用
revenue
子句,都会使用表中存储的结果。 -
查询执行完成之后,临时表会删除。