具有大量子句的SQL'LIKE'语句的效率

时间:2009-11-20 17:52:08

标签: sql sql-server-2005 string performance search

我需要从文本字段中提取信息,该字段可以包含许多值中的一个。 SQL看起来像:

SELECT fieldname
FROM table
WHERE bigtextfield LIKE '%val1%'
   OR bigtextfield LIKE '%val2%'
   OR bigtextfield LIKE '%val3%'
   .
   .
   .
   OR bigtextfield LIKE '%valn%'

我的问题是:当数量接近数百,可能数千时,效率有多高?有更好的方法吗?

一种解决方案是创建一个新的表/列,其中只包含我之后的值并执行以下操作:

SELECT fieldname
FROM othertable
WHERE value IN ('val1', 'val2', 'val3', ... 'valn')

我认为它更有效率,因为它只需要进行精确的字符串匹配。这样做的问题是保持这个表最新是很多工作。

btw我正在使用MS SQL Server 2005。

4 个答案:

答案 0 :(得分:5)

此功能已存在于大多数SQL引擎中,包括MS SQL Server 2005.它被称为全文索引;这里有一些资源:

答案 1 :(得分:2)

我不认为主要问题是标准值的数字 - 但是带有bigtextfield LIKE '%val1%'的WHERE子句永远不会真正高效的纯粹事实 - 即使只是一个单一价值。

问题在于,如果您在搜索字词的开头有一个占位符,例如“%”,则所有索引都在窗口外,不能再使用了。

因此,您基本上只是搜索表中的每个条目,在此过程中执行全表扫描。现在你的表现基本上只取决于你表中的行数....

我会支持intgr的建议 - 如果你需要经常这样做,请认真研究全文索引。

答案 2 :(得分:1)

这将不可避免地要求使用过滤器进行全扫描(在表上或索引上)。

IN条件在此无效,因为它不适用于LIKE

你可以这样做:

SELECT  *
FROM    master
WHERE   EXISTS
        (
        SELECT  NULL
        FROM    values
        WHERE   name LIKE '%' + value + '%'
        )

,但这几乎没有效率。

所有文字条件都将转换为CONSTANT SCAN,这就像从同一个表中选择,但内置在内存中。

答案 3 :(得分:1)

对此最好的解决方案是重新设计并删除存储多个值的字段,并使其成为相关表。这违反了数据库设计的第一条规则之一。

你不应该在一个字段中存储多个值,而这样的死慢查询就是这个原因。如果你不能这样做,那么全面测试索引是你唯一的希望。