10

我有一个简单的查询,它依赖于两个全文索引表,但是当我将CONTAINS与任何其他OR搜索结合使用时,它的运行速度非常慢。从执行计划中可以看出,两次全文搜索压垮了性能。如果我只使用 1 个 CONTAINS 进行查询,或者两者都不查询,则查询是亚秒级的,但是当您将OR添加到组合中时,查询将变得命运多舛。

这两张表没有什么特别之处,它们并不太宽(一张有 42 列,另一张有 21 列;每个列中可能有 10 列被 FT 索引),甚至包含非常多的记录(两者中最大的有 36k 条记录)。

我能够通过将两个CONTAINS搜索拆分为它们自己的SELECT查询然后将这三个合并在一起来解决性能问题。这个 UNION 解决方法是我唯一的希望吗?

SELECT     a.CollectionID
FROM       collections    a
INNER JOIN determinations b ON a.CollectionID = b.CollectionID 
WHERE      a.CollrTeam_Text LIKE '%fa%'
           OR CONTAINS(a.*, '"*fa*"')
           OR CONTAINS(b.*, '"*fa*"')

执行计划:

执行计划

4

4 回答 4

6

我很想知道等价的 CONTAINSTABLE 的 LEFT JOIN 是否会表现得更好。就像是:

SELECT     a.CollectionID
FROM       collections    a
INNER JOIN determinations b ON a.CollectionID = b.CollectionID 
LEFT JOIN CONTAINSTABLE(a, *, '"*fa*"') ct1 on a.CollectionID = ct1.[Key]
LEFT JOIN CONTAINSTABLE(b, *, '"*fa*"') ct2 on b.CollectionID = ct2.[Key]
WHERE      a.CollrTeam_Text LIKE '%fa%'
           OR ct1.[Key] IS NOT NULL
           OR ct2.[Key] IS NOT NULL
于 2010-05-25T18:19:31.597 回答
3

我打算向UNION每个人建议他们自己的查询,但是当我阅读您的问题时,我看到您已经找到了。我想不出更好的方法,所以如果它有助于使用它。该UNION方法是用于处理性能不佳的查询的常用方法,该查询具有多个 OR 条件,其中每个条件都单独执行良好。

于 2010-05-25T17:27:35.013 回答
1

我可能会使用UNION。如果你真的反对它,你可以尝试这样的事情:

SELECT a.CollectionID
FROM collections a
  LEFT OUTER JOIN (SELECT CollectionID FROM collections WHERE CONTAINS(*, '"*fa*"')) c
    ON c.CollectionID = a.CollectionID
  LEFT OUTER JOIN (SELECT CollectionID FROM determinations WHERE CONTAINS(*, '"*fa*"')) d
    ON d.CollectionID = a.CollectionID
WHERE a.CollrTeam_Text LIKE '%fa%'
   OR c.CollectionID IS NOT NULL
   OR d.CollectionID IS NOT NULL
于 2010-05-25T17:41:53.420 回答
0

我们遇到了完全相同的问题,当时,把它归结为我们的查询格式错误——SQL 2005 让我们侥幸逃脱,但 2008 不会。

最后,我们将查询拆分为 2 个使用 IF 调用的 SELECT。很高兴其他人遇到了同样的问题,并且这是一个已知问题。我们在一个表上看到约 150,000 行 + 全文从 < 1 秒 (2005) 到 30+ 秒 (2008) 的查询。

于 2010-05-25T20:19:58.260 回答