Sql server 具有相同外键的左联接表:哈希键探测占50%
我们有3张桌子:Sql server 具有相同外键的左联接表:哈希键探测占50%,sql-server,hash,left-join,sql-execution-plan,Sql Server,Hash,Left Join,Sql Execution Plan,我们有3张桌子: 表0,包含ID(=主键) 表1中包含表0中ID的可为空FK 表2包含表0中ID的可为空FK 我们的查询运行速度太慢,即使索引正确。在查看执行计划(SQL Server 2014)时,他在左侧外部连接上浪费了大量时间。SQL server使用“哈希匹配”,使其成为一个内部联接,成本为47%(如果我没有在where子句中显式设置[FI].[pId]=[FPF].[pId],则成本为50%) 解释说他对[FI].[pId]使用了一个“散列键探测” SELECT [FI].[ID
- 表0,包含ID(=主键)
- 表1中包含表0中ID的可为空FK
- 表2包含表0中ID的可为空FK
[FI].[pId]=[FPF].[pId]
,则成本为50%)
解释说他对[FI].[pId]使用了一个“散列键探测”
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]
我甚至尝试过将table0与主键链接起来,但是没有任何区别。同样,使用外部应用也会得到相同的结果。我也一直在两张表上使用索引,但没有任何利润
有没有人可以分享一些关于我在这里可能做错了什么的想法?尽量减少在左侧连接上返回的记录数 您只对[Table2]中具有特定@name和@tID的记录感兴趣,因此在连接点限制[Table2]结果集的大小
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]
在[表2]中,使用以下索引:
CREATE NONCLUSTERED INDEX idx ON [Table2](pID) INCLUDE (tId,Name)
额外的代码可以将查询转换为内部联接。那会更快
[FI].[pId] = [FPF].[PId] AND -- If I add this explicitly, the query is already a lot faster
您真的需要按订购吗?如果没有,则将其删除。通过在建议的索引中添加数据来解决,并将其添加到pid之前。
由于实际行数和估计行数之间的巨大差异,显示统计数据的执行计划已过时,但内部联接使情况变得更糟。因此,请使用“更新统计信息”或sp_updatestats更新表的统计信息。嗨,buddi,谢谢你的提示。我只是这么做了,但结果是sameOR往往是罪魁祸首,试试Union吧。谢谢你的提示。它会导致最终的结果。