联接提示 (Transact-SQL)

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例Microsoft Fabric 中的 SQL 分析终结点Microsoft Fabric 中的仓库Microsoft Fabric 中的 SQL 数据库

联接提示用于指定查询优化器在 SQL Server 的两个表之间强制执行联接策略。 有关联接和联接语法的常规信息,请参阅 FROM 子句和 JOIN、APPLY、PIVOT。

Caution

由于 SQL Server 查询优化器通常会为查询选择最佳执行计划,因此我们建议仅在最后迫不得已的情况下才可由资深的开发人员和数据库管理员使用提示。

适用于

Transact-SQL 语法约定

Syntax

<join_hint> ::=
     { LOOP | HASH | MERGE | REMOTE | REDUCE | REPLICATE | REDISTRIBUTE [(columns count)]}

Arguments

{ 循环 |哈希 | MERGE }

适用于: Azure SQL 数据库、Azure SQL 托管实例、Microsoft Fabric 中的 SQL 分析终结点、Microsoft Fabric 中的 SQL 数据库、Microsoft Fabric 中的 fabric Warehouse Microsoft

指定查询中的联接应使用循环、哈希或合并。 使用LOOP或HASHMERGE JOIN强制执行两个表之间的特定联接。 LOOP 不能与 RIGHT 联接 FULL 类型或联接类型一起指定。 有关详细信息,请参阅联接。

REMOTE

适用于: Azure SQL 数据库、Azure SQL 托管实例、Microsoft Fabric 中的 SQL 分析终结点、Microsoft Fabric 中的 SQL 数据库

指定联接操作在右表处执行。 这在左表是本地表而右表是远程表的情况下很有用。 REMOTE 仅当左表的行数少于右表时,才应使用。

如果右表为本地表,则联接在本地执行。 如果这两个表都是远程表,但来自不同数据源, REMOTE 则会导致联接在正确的表的站点上执行。 如果这两个表都是来自同一数据源的远程表, REMOTE 则不需要。

REMOTE 在使用子句将联接谓词中要比较的值之一转换为其他排序规则时,不能使用 COLLATE 。

REMOTE 只能用于 INNER JOIN 操作。

REDUCE

适用对象:Azure Synapse Analytics

减少联接右侧表中要移动的行的数量,以使两个分布不兼容表实现兼容。 REDUCE 提示也称为半联接提示。

REPLICATE

适用于:Azure Synapse Analytics,Microsoft Fabric 中的 Microsoft Fabric 仓库

导致广播移动作,其中特定表将在所有分发节点之间复制。

  • 使用具有 REPLICATE 或 INNER 联接的 LEFT,广播移动作会将联接右侧复制到所有节点。
  • 同样,在 REPLICATE 联接中使用 RIGHT 时,广播移动作会将联接的左侧复制到所有节点。
  • 将 REPLICATE 用于 FULL 联接时,无法创建估计的计划。

重新分配[(columns_count)]

适用对象:Azure Synapse Analytics

强制两个数据源分布到 JOIN 子句中指定的列上。 对于分布式表,Azure Synapse Analytics 会对两个表的第一列进行洗牌移动。对于复制表,Azure Synapse Analytics 会进行修剪移动。 当查询计划使用 broadcast 移动解决分布不兼容联接时,此提示可提高性能。

适用于: Microsoft Fabric 中的 Microsoft Fabric 仓库

REDISTRIBUTE 提示确保基于 JOIN 子句列分布两个数据源。 它处理由两个表中第一个 n 列指定的多个联接条件,其中 n 是 column_count 参数。 在执行中间步骤期间,重新分发数据可优化查询性能,从而在节点之间均匀分布数据。

该 (columns_count) 参数仅在 Microsoft Fabric Microsoft Fabric Warehouse 中受支持。

Remarks

联接提示在查询的子句中 FROM 指定。 联接提示可以在两个表之间强制执行联接策略。 如果为任意两个表指定了联接提示,则查询优化器将根据关键字的位置自动强制实施查询中所有联接表的 ON 联接顺序。 在没有子句的情况下CROSS JOIN使用 a ON 时,括号可用于指示联接顺序。

Examples

本文中的代码示例使用AdventureWorks2025了 、 AdventureWorksDW2025或AdventureWorksLT2025示例数据库,您可以从 Azure Data SQL Samples Repository 的 GitHub 仓库下载。

A. 使用哈希

下面的示例指定查询中的 JOIN 操作由 HASH 联接执行。

SELECT p.Name,
    pr.ProductReviewID
FROM Production.Product AS p
LEFT OUTER HASH JOIN Production.ProductReview AS pr
    ON p.ProductID = pr.ProductID
ORDER BY ProductReviewID DESC;

B. 使用LOOP

下面的示例指定查询中的 JOIN 操作由 LOOP 联接执行。

DELETE
FROM Sales.SalesPersonQuotaHistory
FROM Sales.SalesPersonQuotaHistory AS spqh
INNER LOOP JOIN Sales.SalesPerson AS sp
    ON spqh.SalesPersonID = sp.SalesPersonID
WHERE sp.SalesYTD > 2500000.00;
GO

C. 使用 MERGE

下面的示例指定查询中的 JOIN 操作由 MERGE 联接执行。

SELECT poh.PurchaseOrderID,
    poh.OrderDate,
    pod.ProductID,
    pod.DueDate,
    poh.VendorID
FROM Purchasing.PurchaseOrderHeader AS poh
INNER MERGE JOIN Purchasing.PurchaseOrderDetail AS pod
    ON poh.PurchaseOrderID = pod.PurchaseOrderID;
GO

D. REDUCE 联接提示示例

下面的示例使用 REDUCE 联接提示更改对查询内的派生表的处理。 此查询中使用 REDUCE 联接提示时,fis.ProductKey 将被投影、复制和进行区别处理,然后在对 DimProduct 上的 DimProduct 执行 shuffle 时联接到 ProductKey。 生成的派生表将分布在 fis.ProductKey 上。

-- Uses AdventureWorks
  
SELECT SalesOrderNumber
FROM (
    SELECT fis.SalesOrderNumber,
        dp.ProductKey,
        dp.EnglishProductName
    FROM DimProduct AS dp
    INNER REDUCE JOIN FactInternetSales AS fis
        ON dp.ProductKey = fis.ProductKey
    ) AS dTable
ORDER BY SalesOrderNumber;

E. REPLICATE 联接提示示例

本示例演示与上一示例相同的查询,但使用的是 REPLICATE 联接提示,而非 REDUCE 联接提示。 使用 REPLICATE 提示会导致 ProductKey 表中的 FactInternetSales(联接)列复制到所有节点。 DimProduct 表将与这些值的复制版本进行联接。

-- Uses AdventureWorks

SELECT SalesOrderNumber
FROM (
    SELECT fis.SalesOrderNumber,
        dp.ProductKey,
        dp.EnglishProductName
    FROM DimProduct AS dp
    INNER REPLICATE JOIN FactInternetSales AS fis
        ON dp.ProductKey = fis.ProductKey
    ) AS dTable
ORDER BY SalesOrderNumber;

F. 使用 REDISTRIBUTE 提示以保证对分布不兼容联接使用 Shuffle 移动

以下查询对分发不兼容联接使用 REDISTRIBUTE 查询提示。 这能确保查询优化器在查询计划中使用 Shuffle 移动。 这还可确保查询计划不会使用可将分布表移动到复制表的 Broadcast 移动。

在以下示例中,REDISTRIBUTE 提示强制 FactInternetSales 表中的随机移动,因为 ProductKey 是 DimProduct的分布列,不是 FactInternetSales的分布列。

-- Uses AdventureWorks
  
SELECT dp.ProductKey,
    fis.SalesOrderNumber,
    fis.TotalProductCost
FROM DimProduct AS dp
INNER REDISTRIBUTE JOIN FactInternetSales AS fis
    ON dp.ProductKey = fis.ProductKey;

G. 将列计数参数与 REDISTRIBUTE 提示配合使用

以下查询使用具有列计数参数的 REDISTRIBUTE 查询提示,并且随机排列发生在联接中每个表的前四列。

SELECT * FROM DA
INNER REDISTRIBUTE (4) JOIN DB
ON DA.a1 = DB.b1