了解 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_products
表product_id
列中的 IDs。
示例 1:消除不必要的左外联接¶
以下是 Snowflake 可以优化的不必要的左外连接示例:
SELECT f.*
FROM fact_sales f
LEFT OUTER JOIN dim_products p
ON f.product_id = p.product_id;
联接是不必要的,因为该语句不引用右侧 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;
该语句不必要地将 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;
该语句不引用右侧 dim_products
表中的任何列,但联接的主键列除外。
如果 dim_products.product_id
列存在 PRIMARY KEY 约束,并且 fact_sales.product_id
列存在 FOREIGN KEY 约束,则 Snowflake 可以将此联接标识为不必要,并可以消除对右侧 dim_products
表的引用。