sql - 涉及 CONTAINS 和 OR 的慢速 SQL 查询

标签 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 文件组成。

关于为什么第一个查询如此缓慢,我们没有好的理论,所以我们希望这里有人能就此事发表一些明智的看法。据我们所知,查询计划没有显示任何异常。我们还重建了索引和统计信息。

有什么明显明显的东西是我们忽略的吗?

在此先感谢您的时间!

最佳答案

您为什么使用 DescriptionColumn LIKE '%WhatEver%'而不是 CONTAINS(DescriptionColumn, '"WhatEver"') ?
CONTAINS显然是一个全文谓词,将使用 SQL Server 全文引擎来过滤搜索结果,但是 LIKE是一个“正常”的 SQL Server 关键字,因此 SQL Server 不会使用全文引擎来协助此查询 - 在这种情况下,因为 LIKE术语以通配符开头 SQL Server 将无法使用任何索引来帮助查询,这很可能会导致表扫描和/或比使用全文引擎更差的性能。

如果没有执行计划,很难判断,但是我对发生的事情的猜测是:

  • UNION查询的变体是对 table1 执行表扫描- 表扫描并不快,但是因为表中的行相对较少,所以它的执行速度并不慢(与 35 秒基准相比)。
  • OR查询的变体 SQL Server 首先使用全文引擎根据 CONTAINS 进行过滤。然后继续对结果中的每个匹配行执行 RDI 查找以根据 LIKE 进行过滤。谓词,但是由于某种原因,SQL Server 大大低估了行数(这可能发生在某些类型的谓词中),因此继续执行数以千计的 RDI 查找,结果非常慢(表扫​​描会快得多) )。

  • 要真正了解正在发生的事情,您需要获得一个查询计划。

    关于sql - 涉及 CONTAINS 和 OR 的慢速 SQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6534322/

    相关文章:

    mysql - 根据Mysql中的两列获取最小值

    更改列格式的 SQL 函数

    c# - 当 SQL Server 中用户定义的表类型将所有列的默认值设置为 null 时,如何将具有较少列的 DataTable 传递给存储过程

    sql-server - SQL Server 2008安装错误消息: Unable to open windows installer file

    mysql - 如何将 NOT IN 子查询重写为连接

    mysql - Magento 让 MySQL 每天崩溃 1 到 2 次

    java - Eclipse 速度极慢,持续阻塞在 NonEssentialElementsFilter.hasFilteredChildren

    python - urllib.urlopen() 如何工作?

    Android:尝试设置到 ImageView 时联系人照片像素化

    sql - 如何编写SQL Server数据库角色脚本?