使用CONTAINS添加更多OR搜索带来查询以进行爬网

时间:2010-05-25 17:15:02

标签: sql-server sql-server-2008 full-text-search full-text-indexing

我有一个简单的查询依赖于两个全文索引表,但是当我将 CONTAINS 与任何其他 OR 搜索结合使用时,它运行得非常慢。正如执行计划中所见,这两个全文搜索会破坏性能。如果我只查询其中一个CONTAINS,或者两者都不查询,则查询是亚秒级的,但是当您将 OR 添加到混合中时,查询就会变得不合时宜。

这两张表没什么特别的,它们不是太宽(一个是42个,另一个是21个;可能每个10个列都是FT索引),甚至包含很多记录(最大的36个记录)二)。

我能够通过将两个 CONTAINS 搜索分成他们自己的 SELECT 查询然后将 UNION 三个一起分解来解决性能问题。 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*"')

执行计划(我想在发布图片之前需要更多声誉):http://yfrog.com/7dslowcontainsj http://desmond.yfrog.com/Himg265/scaled.php?tn=0&server=265&filename=slowcontains.jpg&xsize=640&ysize=640

4 个答案:

答案 0 :(得分:6)

我很想知道LEFT JOIN到等效的CONTAINSTABLE是否会更好。类似的东西:

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

答案 1 :(得分:3)

我打算建议每个UNION作为他们自己的查询,但当我读到你的问题时,我看到你已经找到了。我想不出更好的方法,所以如果它有助于使用它。 UNION方法是执行性能较差的查询的常用方法,该查询具有多个OR条件,每个条件都可以自行执行。

答案 2 :(得分: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

答案 3 :(得分:0)

我们遇到了完全相同的问题,当时,我们的查询结果很糟糕 - SQL 2005让我们逃脱了它,但2008年不会。

最后,我们将查询拆分为2个使用IF调用的SELECT。很高兴其他人有同样的问题,这是一个已知的问题。我们在一张桌子上看到了大约150,000行+全文来自< 1秒(2005年)至30秒(2008年)。