具有相同外键的左连接表:哈希键探测占 50%

left join tables which have same foreign key: hash key probe takes 50%

我们有 3 张桌子:

我们的查询运行速度太慢,即使已正确编制索引也是如此。在查看执行计划(SQL Server 2014)时,他在左外连接上浪费了很多时间。 SQL 服务器改为使用 "Hash Match",使其成为内部连接,成本为 47%(如果我没有在 where 子句中明确设置 [FI].[pId] = [FPF].[PId],则成本为 50%)。

execution plan

解释说他对 [FI].[pId] 使用 "hash key probe"。

SELECT [FI].[ID], [FI].[Name], [FI].[Data]
FROM [dbo].[Table1] AS [FI] WITH (NOLOCK)
LEFT JOIN [Table2] AS [FPF] WITH (NOLOCK) ON [FI].[pId] = [FPF].[pId]
WHERE
[FI].[pId] = [FPF].[PId] AND -- If I add this explicitly, the query is already a lot faster
(
(
    [FI].[tId] = @tID --is bigint (FK)
    AND
    [Fi].[Name] = @Name --is varchar
)
OR
(
    [FI].[fiType] = 1
)
OR
(
    [FPF].[tId] = @tID
    AND
    [FPF].[Name] = @Name
))
ORDER BY [Fi].[Data]

我什至还尝试过 link table0 的主键,但这没有什么区别。同样使用外部应用给出相同的结果。我也一直在两个表上玩索引,但没有任何利润。

有人可以分享一些关于我在这里可能做错了什么的想法吗?

尽量减少 LEFT JOIN 返回的可能记录数。

您只对 [Table2] 中具有特定 @name 和 @tID 的记录感兴趣,因此请在连接点限制 [Table2] result-set 的大小。

SELECT [FI].[ID], [FI].[Name], [FI].[Data]
FROM [dbo].[Table1] AS [FI] WITH (NOLOCK)
LEFT JOIN [Table2] AS [FPF] WITH (NOLOCK) ON [FI].[pId] = [FPF].[pId]
                                            AND [FPF].[tId] = @tID
                                            AND [FPF].[Name] = @Name
WHERE
[FI].[pId] = [FPF].[PId] AND -- If I add this explicitly, the query is already a lot faster
(
(
    [FI].[tId] = @tID --is bigint (FK)
    AND
    [Fi].[Name] = @Name --is varchar
)
OR
(
    [FI].[fiType] = 1
)
OR
(
    [FPF].[tId] = @tID
    AND
    [FPF].[Name] = @Name
))
ORDER BY [Fi].[Data]

在 [Table2] 上使用此索引:

CREATE NONCLUSTERED INDEX idx ON [Table2](pID) INCLUDE (tId,Name)

您的额外代码可以将您的查询变成 INNER JOIN。哪个会更快。

[FI].[pId] = [FPF].[PId] AND -- If I add this explicitly, the query is already a lot faster

你真的需要ORDER BY吗?如果没有,那就摆脱它。

通过在建议索引中添加数据解决,在pid之前添加。 不过,内部连接使情况变得更糟