这是参加暗示危险吗?
-
03-07-2019 - |
题
一个同事让我看看索引编制一些表格,因为他的查询正在运行很长时间。超过一个小时。
select count(1)
from databaseA.dbo.table1
inner join databaseA.dbo.table2 on (table1.key = table2.key)
inner join databaseB.dbo.table3 on (table1.key = table3.key)
注意到不同的数据库。这是正在运行,从DatabaseB
表1和表2分别超过2百万个记录的长。Table3有十几个记录。
我看了查询计划和优化决定要做到循环嵌套索引寻求入表1和表2与Table3作为驱动的表!
我的第一个假设是,统计数据是严重的是搞砸了上Tables1和2但是,在更新统计数字,我想添加一个加入提示正是如此:
select count(1)
from databaseA.dbo.table1
inner HASH join databaseA.dbo.table2 on (table1.key = table2.key)
inner join databaseB.dbo.table3 on (table1.key = table3.key)
结果返回,在15秒。
因为我是在很短的时间,我通过了结果反馈到他,但是我担心这可能会导致问题的道路。
我应该重新审查统计数据问题和解决问题的方式?可能坏查询计划已导致从加入正在从一个独立的数据库?
任何人都可以给我提供一些想法,基于你的经验?
解决方案
我会先怀疑统计数据。
正如您无疑所知,99%的情况下应避免使用加入提示,并且只有在您有绝对需要的证明时才使用。
其他提示
首先检查统计信息并对表进行索引。索引提示可能会导致问题。如果表中的数据发生更改,优化程序将无法选择更有效的计划,因为您已强制它始终使用哈希。
嵌套循环不是最合适的吗?取表3中的12条记录,与表1中的12条记录相匹配,匹配表2中的12条记录。
否则,您的散列连接也会强制执行排序 - 这意味着您从表1和表2中散列了100万条记录,然后加入表3中的12条记录。
我会查看两个计划的统计数据 - 我怀疑循环连接实际上更有效,但是被阻止或者您的散列连接正在利用缓存数据。
但是 - 是的 - 总的来说,加入提示是最后的手段。
一个运行速度缓慢涉及查询链接的服务器可能做到有的排序规则。在这里看到的一些背景: http://blogs.msdn.com/psssql/archive/2008/02/14/how-it-works-linked-servers-and-collation-compatibility.aspx 散列加入暗示部队的排序次序,以便解释的性能增益。
这里就如何设置的选择:
EXEC master.dbo.sp_serveroption
@server=N'databaseA',
@optname=N'collation compatible',
@optvalue=N'true'
EXEC master.dbo.sp_serveroption
@server=N'databaseA',
@optname=N'use remote collation',
@optvalue=N'false'
-Edoode