Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 为什么';散列连接';或';循环联接';改进这个存储过程?_Sql_Sql Server_Sql Server 2005_Optimization_Join - Fatal编程技术网

Sql 为什么';散列连接';或';循环联接';改进这个存储过程?

Sql 为什么';散列连接';或';循环联接';改进这个存储过程?,sql,sql-server,sql-server-2005,optimization,join,Sql,Sql Server,Sql Server 2005,Optimization,Join,我有一个从6秒到1秒的基本查询,只需将一个连接从LEFT join更改为LEFT HASH join或“LEFT LOOP join”。有人能解释为什么这会导致性能的大幅提高,以及为什么SQL的优化器不能自己解决这个问题吗 下面是SQL的大致情况: SELECT a.[ID] FROM [TableA] a LEFT HASH JOIN [TableB] b ON b.[ID] = a.[TableB_ID] JOIN [TableC] c ON c.[ID]

我有一个从6秒到1秒的基本查询,只需将一个连接从
LEFT join
更改为
LEFT HASH join
或“LEFT LOOP join”。有人能解释为什么这会导致性能的大幅提高,以及为什么SQL的优化器不能自己解决这个问题吗

下面是SQL的大致情况:

SELECT
   a.[ID]
FROM
   [TableA] a
LEFT HASH JOIN
   [TableB] b
   ON b.[ID] = a.[TableB_ID]
JOIN
   [TableC] c
   ON c.[ID] = a.[TableC_ID]
WHERE
   a.[SomeDate] IS NULL AND
   a.[SomeStatus] IN ('X', 'Y', 'Z') AND
   c.[SomethingElse] = 'ABC'
表A和B在所有ID字段上都有数百万条记录和索引。使用SQLServer2005


编辑:一位同事建议使用左循环连接,这似乎使其速度更快。。。SQL不是我的强项之一,因此我试图理解这些“提示”是如何起作用的。

HASH JOIN
在很大比例的行构成结果集时非常有用

在您的情况下,在
a
B
上构建
哈希表并扫描另一个表比在
B.ID
上的索引上执行
嵌套循环
或合并优化器在提示之前使用的排序结果集更便宜

SQL Server的优化器没有看到这一点:可能是因为您没有收集统计数据,可能是因为您的数据分布不均匀

更新:


由于您提到了
循环联接
提高了速度,这可能是因为优化器错误地选择了
联接
顺序。

在这种情况下,几乎所有行都应该成功地离开联接(例如90%+)。修复了s/分布/分布。另外:看起来你终于在SQLServer统计页面上超过了我的总投票数。我坦率地承认,你在这个问题上更为博学,因此,现在世界的不协调程度有所下降。谢谢,你的回答帮助我理解了为什么会发生这种情况。你能在提示应用之前和之后发布计划吗?只需发出
SET SHOWPLAN\u TEXT ON GO SELECT…
删除所有提示,然后使用show actual plan在SSMS中运行查询,然后在计划中比较计划边缘的扫描/搜索操作符的估计行数与实际行数。计划根据估计的计数生成,持续时间由实际计数驱动。差异表明统计数据不好,但对于异常、奇数值(即碰巧有1 mil.行而不是10行的SomeStatus),也可能发生良好统计数据的差异。