2008-12-31 74 views
2

一位同事要求我查看某些表格的索引,因为他的查询运行时间很长。一个多小时。这个加入提示是否危险?

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中!

我的第一个假设是,统计数据受到严重搞砸上Tables1 & 2,但更新统计之前,我尝试过加入正是如此联接提示:在15秒内返回

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) 

结果。

由于时间不够,我把结果通知给了他,但我担心这可能会导致问题在后面。

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

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

回答

2

我会首先怀疑统计数据。

正如你所知道的,在99%的情况下应该避免加入提示,并且只有当你证明他们是绝对需要时才使用。

1

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

1

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

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

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

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

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