涉及CONTAINS和OR的慢速SQL查询

时间:2011-06-30 11:54:18

标签: sql performance sql-server-2008

我们遇到了一个问题,我们希望Stack Overflow的优秀人员可以帮助我们。我们正在运行SQL Server 2008 R2,并且在查询时遇到问题需要很长时间才能在一组中等数据上运行,大约有100000行。我们使用CONTAINS搜索xml文件,并在另一列上使用LIKE来支持领先的外卡。

我们使用以下小型查询重现了该问题,该查询大约需要35秒才能运行:

SELECT something FROM table1 
WHERE (CONTAINS(TextColumn, '"WhatEver"') OR  
        DescriptionColumn LIKE '%WhatEver%')

查询计划:

Slow query

如果我们将上面的查询修改为使用UNION,则运行时间从35秒下降到< 1秒我们希望避免使用这种方法来解决问题。

SELECT something FROM table1 WHERE (CONTAINS(TextColumn, '"WhatEver"') 
UNION
(SELECT something FROM table1 WHERE (DescriptionColumn LIKE '%WhatEver%'))

查询计划:

Fast query

我们使用CONTAINS进行搜索的列是一个类型为image的列,由大小为1k到20k的xml文件组成。

我们没有很好的理论为什么第一个查询是如此缓慢,所以我们希望有人在这个问题上有明智的说法。据我们所知,查询计划并没有显示任何异常。我们还重建了索引和统计数据。

有什么明显的东西我们在这里俯瞰吗?

提前感谢您的时间!

3 个答案:

答案 0 :(得分:4)

为什么使用DescriptionColumn LIKE '%WhatEver%'代替CONTAINS(DescriptionColumn, '"WhatEver"')

CONTAINS显然是一个全文谓词,并将使用SQL Server全文引擎来过滤搜索结果,但LIKE是一个“普通”SQL Server关键字,所以SQL Server将不使用全文引擎来执行此查询 - 在这种情况下,因为LIKE术语以通配符开头SQL Server将无法使用任何索引来帮助查询,这很可能会导致与使用全文引擎相比,表扫描和/或性能较差。

如果没有执行计划,很难无法判断,但是我对最新情况的猜测是:

  • 查询的UNION变体正在对table1执行表扫描 - 表扫描速度不快,但是因为表中的行数相对较少而没有执行< em>那缓慢(与35s基准相比)。

  • 在查询的OR变体中,SQL Server首先使用全文引擎根据CONTAINS进行过滤,然后继续在每个匹配的行上执行RDI查找在基于LIKE谓词过滤的结果中,但由于某种原因,SQL Server大量低估了行数(这可能发生在某些类型的谓词中),因此继续执行几个thousnad RDI查找,结束速度非常慢(桌面扫描速度会快得多)。

要真正了解最新情况,您需要制定一个查询计划。

答案 1 :(得分:1)

你们这样做了吗:

SELECT *
FROM table
WHERE CONTAINS((column1, column2, column3), '"*keyword*"')  

而不是:

SELECT *
FROM table
WHERE CONTAINS(column1, '"*keyword*"') 
OR CONTAINS(column2, '"*keyword*"') 
OR CONTAINS(column3y, '"*keyword*"') 

第一个更快。

答案 2 :(得分:1)

我刚碰到这个。据报道,这是SQL Server 2008 R2上的一个错误:

http://www.arcomit.co.uk/support/kb.aspx?kbid=000060

使用UNION of two选择而不是OR的方法是他们在该文章中推荐的解决方法。