我有一个简单的查询依赖于两个全文索引表,但是当我将 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
答案 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年)。