了解 Snowflake 如何消除冗余联接

在某些情况下,键列上的联接可以引用执行联接时不需要的表。如果表有键列,并且您正在使用和强制执行 UNIQUE、PRIMARY KEY 和 FOREIGN KEY 约束,则 Snowflake 可以通过消除键列上不必要的联接来提高查询性能。

仅当使用 RELY 约束属性来指示表中的数据符合有关主键和外键的约束时,才会执行这些优化。

本主题内容:

设置 RELY 约束属性以消除不必要的联接

Snowflake 仅在您指示表中数据符合 UNIQUE、PRIMARY KEY 和 FOREIGN KEY 约束时,才对联接执行此优化。

如:ref:`label-constraints-supported-types`中所述,Snowflake 不强制执行 UNIQUE、PRIMARY KEY 和 FOREIGN KEY 约束。您负责对表中数据强制执行这些约束。

如果已确保数据符合这些约束,并且希望 Snowflake 消除不必要联接,请在 UNIQUE、PRIMARY KEY、FOREIGN KEY 约束上设置 RELY 约束属性。

备注

您有责任维护约束(UNIQUE、PRIMARY KEY 和 FOREIGN KEY)的完整性。如果未保持约束的完整性,则在设置了 RELY 约束属性时,查询结果可能会有所不同(对比使用 NORELY 的结果而言)。

消除不必要联接的示例

以下示例演示了 Snowflake 消除不必要的表联接和引用的情况:

在这些示例中:

  • dim_products 是一个表,其中包含可购买的每种产品的行。

    在此表中,product_id 是唯一标识产品的列。

  • fact_sales 是一个表,其中包含产品每次销售的行。

    在此表中,product_id 是标识已售出产品的列。此列中的 IDs 对应于 dim_productsproduct_id 列中的 IDs。

示例 1:消除不必要的左外联接

以下是 Snowflake 可以优化的不必要的左外连接示例:

SELECT f.*
FROM fact_sales f
LEFT OUTER JOIN dim_products p
ON f.product_id = p.product_id;
Copy

联接是不必要的,因为该语句不引用右侧 dim_products 表中的任何列(联接的主键列除外)。

如果 dim_products.product_id 列存在带有 RELY 属性的 UNIQUE 或 PRIMARY KEY 约束,则 Snowflake 可以将此联接标识为不必要,并且可以消除对右侧 dim_products 表的引用。

示例 2:消除不必要的自联接

以下是 Snowflake 可以优化的不必要的自联接示例:

SELECT p1.product_id, p2.product_name
FROM dim_products p1, dim_products p2
WHERE p1.product_id = p2.product_id;
Copy

该语句不必要地将 dim_products 表与自身进行了联接 ,并从该表中选择了列。

如果 dim_products.product_id 列存在带有 RELY 属性的 UNIQUE 或 PRIMARY KEY 约束,则 Snowflake 可以将此联接标识为不必要,并且可以消除对右侧 dim_products 表的引用。

示例 3:消除主键和外键上的不必要联接

以下是 Snowflake 可以优化的不必要的内部联接示例。

SELECT p.product_id, f.units_sold
FROM   fact_sales f, dim_products p
WHERE  f.product_id = p.product_id;
Copy

该语句不引用右侧 dim_products 表中的任何列,但联接的主键列除外。

如果 dim_products.product_id 列存在 PRIMARY KEY 约束,并且 fact_sales.product_id 列存在 FOREIGN KEY 约束,则 Snowflake 可以将此联接标识为不必要,并可以消除对右侧 dim_products 表的引用。

语言: 中文