5

谁能解释这种行为或如何解决它?

如果执行此查询:

select * 
from TblA
left join freetexttable ( TblB, *, 'query' ) on TblA.ID = [Key]
inner join DifferentDbCatalog.dbo.TblC on TblA.ID = TblC.TblAID

这将非常非常非常慢。

如果您将该查询更改为使用两个内连接而不是左连接,它将非常快。如果您将其更改为使用两个左连接而不是内连接,它将非常快。

如果您也使用 sql 表变量而不是 freetexttable,则可以观察到相同的行为。

每当您有一个表变量(或 freetexttable)和一个位于不同数据库目录中的表时,性能问题就会出现,其中一个在内部联接中,另一个在左联接中。

有谁知道为什么这很慢,或者如何加快速度?

4

4 回答 4

8

一般的经验法则是 OUTER JOIN 会导致结果集中的行数增加,而 INNER JOIN 会导致结果集中的行数减少。 当然,也有很多情况正好相反,但这种情况更有可能发生。您想要为性能做的就是尽可能长时间地保持结果集(工作集)的大小尽可能小。

由于两个连接都在第一个表上匹配,因此更改顺序不会影响结果的准确性。因此,您可能希望在 LEFT JOIN 之前执行 INNER JOIN:

SELECT * 
FROM TblA
INNER JOIN DifferentDbCatalog.dbo.TblC on TblA.ID = TblC.TblAID
LEFT JOIN freetexttable ( TblB, *, 'query' ) on TblA.ID = [Key]

实际上,查询优化器应该足够聪明,可以编译以使用更快的选项,而不管您为连接指定的顺序如何。但是,最好假设您有一个愚蠢的查询优化器,并且查询操作是按顺序发生的。这有助于未来的维护人员发现有关表性质的潜在错误或假设。

因为优化器应该重写东西,这可能不足以完全解释您所看到的行为,所以您仍然需要检查用于每个查询的执行计划,并可能按照前面的建议添加一个索引. 不过,这仍然是一个很好的学习原则。

于 2008-09-06T00:20:56.577 回答
4

您通常应该做的是打开“显示实际执行计划”选项,然后仔细查看导致减速的原因。(将鼠标悬停在每个连接上以查看详细信息)您需要确保获得的是索引搜索而不是表扫描。

我会假设正在发生的事情是 SQL 被迫将所有内容从一个表拉到内存中,以便执行其中一个连接。有时颠倒加入表格的顺序也会有所帮助。

于 2008-09-06T00:11:05.850 回答
0

索引用于执行连接的字段。

一个好的经验法则是将索引分配给任何经常引用的键或候选键

于 2008-09-06T00:02:38.633 回答
0

freetexttable(TblB, *, 'query')如果在执行计划中重复调用它,则放入临时表可能会有所帮助。

于 2008-09-06T00:24:31.217 回答