WITH 子句的实体化

实体化启用之后,Vertica 会对每个 WITH 子句进行一次评估,将结果存储在临时表中,然后在查询需要时引用此表。主要查询执行完成之后,Vertica 会将临时表删除。

如果 WITH 子句非常复杂,例如当 WITH 子句包含 JOIN 和 GROUP BY 子句,并且在主要查询中多次被引用时,实体化可帮助提高性能。

如果实体化已启用,WITH 语句会自动提交用户事务。即使将 EXPLAIN 与 WITH 语句一起使用,也是如此。

启用 WITH 子句实体化

WITH 实体化由配置参数 WithClauseMaterialization 设置,默认设置为 0(禁用)。您可以分别使用 ALTER DATABASEALTER 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 DATABASEALTER 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 按以下方式处理此查询:

  1. WITH 子句 revenue 通过 store.store_orders_fact 表评估 SELECT 语句。

  2. revenue 子句的结果存储在本地临时表中。

  3. 无论何时引用 revenue 子句,都会使用表中存储的结果。

  4. 查询执行完成之后,临时表会删除。