这个加入暗示危险吗?

时间:2008-12-31 01:56:36

标签: sql join sql-server-2000 join-hints

一位同事让我看一些表上的索引,因为他的查询运行时间很长。一个多小时。

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的记录长度超过200万条。表3有十几条记录。

我查看了查询计划,优化器决定使用Table3作为驱动表,对表1和表2进行嵌套循环索引查找!

我的第一个假设是,统计数据严重搞乱了表格1& 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秒后返回。

由于时间紧迫,我将结果传回给他,但我担心这可能会导致问题。

我应该重新审视统计问题并以这种方式解决问题吗?错误的查询计划是否来自于来自单独数据库的连接?

任何人都可以根据您的经验向我提供一些想法吗?

4 个答案:

答案 0 :(得分:2)

我会先怀疑统计数据。

正如您无疑所知,99%的情况下应避免使用加入提示,并且只有在您有证据证明绝对需要时才使用。

答案 1 :(得分:1)

首先检查统计信息并对表进行索引。索引提示可能会导致问题。如果表中的数据发生更改,优化程序将无法选择更有效的计划,因为您已强制它始终使用哈希。

答案 2 :(得分:1)

嵌套循环不是最合适的吗?取表3中的12条记录,与表1中的12条记录相匹配,匹配表2中的12条记录。

否则,您的散列连接也会强制执行排序 - 这意味着您从表1和表2中散列了100万条记录,然后加入表3中的12条记录。

我会查看两个计划的统计数据 - 我怀疑循环连接实际上更有效,但是被阻止或者您的散列连接正在利用缓存数据。

但是 - 是的 - 总的来说,加入提示是最后的手段。

答案 3 :(得分:1)

涉及链接服务器的慢速查询可能与排序规则有关。 请参阅此处了解背景信息: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