内部和左侧连接导致SQL查询速度慢?

时间:2008-09-05 23:53:47

标签: sql-server performance freetext

任何人都可以解释这种行为或如何绕过它吗?

如果您执行此查询:

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

非常非常慢。

如果您更改该查询以使用两个内部联接而不是左联接,那么它将非常快。如果将其更改为使用两个左连接而不是内连接,则速度非常快。

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

只要有一个表变量(或自由文本表)和一个表在不同的数据库目录中,其中一个在内连接中而另一个在左连接中,就会出现性能问题。

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

4 个答案:

答案 0 :(得分:7)

一般的经验法则是,OUTER JOIN会导致结果集中的行数增加,而INNER JOIN会导致结果集中的行数减少。< / em>当然,有很多情况下相反的情况也是如此,但它更有可能以这种方式工作而不是。您要为性能做的是尽可能地保持结果集(工作集)的大小尽可能小。

由于两个连接在第一个表上匹配,因此更改顺序不会影响结果的准确性。因此,您可能希望在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]

实际上,无论您为连接指定了哪个顺序,查询优化器都应该足够聪明,可以编译以使用更快的选项。但是,最好假装您有一个愚蠢的查询优化器,并且查询操作按顺序进行。这有助于未来的维护者发现有关表格性质的潜在错误或假设。

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

答案 1 :(得分:3)

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

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

答案 2 :(得分:0)

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

一个好的经验法则是为任何通常引用的foreigncandidate keys分配索引。

答案 3 :(得分:0)

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