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 万条。Table3 有十几条记录。

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

我的第一个假设是 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 秒内返回。

由于时间紧迫,我将结果反馈给了他,但我担心这可能会导致以后出现问题。

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

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

4

4 回答 4

2

我会首先怀疑统计数据。

毫无疑问,您应该知道,在 99% 的情况下应该避免加入提示,并且只有在您有证据证明它们是绝对需要时才使用它们。

于 2008-12-31T01:59:24.503 回答
1

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

于 2008-12-31T02:21:30.620 回答
1

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

否则,您的哈希连接也会强制执行排序——这意味着您将从表 1 和表 2 中对 100 万条记录进行哈希处理,然后连接到表 3 中的 12 条记录。

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

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

于 2008-12-31T03:17:30.507 回答
1

涉及链接服务器的运行缓慢的查询可能与排序规则有关。有关一些背景信息,请参见此处:http: //blogs.msdn.com/psssql/archive/2008/02/14/how-it-works-linked-servers-and-collat ​​ion-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

于 2009-01-21T15:01:20.640 回答