我们有一个查询运行一个相当大的表,不幸的是需要在一些varchar字段上使用LIKE'%ABC%',以便用户可以搜索部分名称等.SQL Server 2005

在使用LIKE时,在这些varchar字段上添加索引是否有助于选择查询性能,还是基本上忽略索引并在这些情况下执行完整扫描?

使用LIKE时提高性能的其他任何可能方法?

有帮助吗?

解决方案

仅当您向这些列添加全文搜索,并使用SQL Server的全文查询功能时。

否则,不,索引无济于事。

其他提示

您可以通过添加索引来看到性能改进,这在很大程度上取决于细节:)

行的总大小中有多少是您的谓词列?您希望匹配多少行?您是否需要返回与谓词匹配的所有行,或者只返回前1行或前n行?

如果要搜索具有高选择性/唯一性的值(返回的行数很少),并且谓词列是整个行大小的一小部分,则索引可能非常有用。它仍然是一个扫描,但是你的索引每页的行数比源表更多。

以下是一个示例,其中总行大小远远大于要搜索的列大小:

create table t1 (v1 varchar(100), b1 varbinary(8000))
go
--add 10k rows of filler
insert t1 values ('abc123def', cast(replicate('a', 8000) as varbinary(8000)))
go 10000
--add 1 row to find
insert t1 values ('abc456def', cast(replicate('a', 8000) as varbinary(8000)))
go

set statistics io on 
go
select * from t1 where v1 like '%456%'
--shows 10001 logical reads

--create index that only contains the column(s) to search across
create index t1i1 on t1(v1)
go
select * from t1 where v1 like '%456%'
--or can force to 
--shows 37 logical reads

如果查看实际的执行计划,您可以看到引擎扫描了索引并在匹配的行上进行了书签查找。或者您可以直接告诉优化器使用索引,如果它还没有决定自己使用此计划: 从t1选择*(索引(t1i1)),其中v1喜欢'%456%'

如果您有一堆列只能搜索一些具有高度选择性的列,您可以创建多个索引并使用缩减方法。例如。首先从高选择性索引中确定一组ID(或者你的PK是什么),然后用针对那一小组PK的过滤器搜索你的选择性较低的列。

如果您总是需要返回大量行,那么使用表扫描几乎肯定会更好。

因此,可能的优化很大程度上取决于表定义的具体情况和数据的选择性。

HTH! -Adrian

除了使用全文索引之外,您可以提高性能的另一种方法是使用“LIKE ABC%”。 - 不要在搜索词的两端添加通配符 - 在这种情况下,索引可以正常工作。

如果您的要求必须在搜索字词的两端都有通配符,那么您就不幸了......

马克

与'%ABC%'一样,将始终执行全表扫描。没有办法解决这个问题。

您确实有几种替代方法。首先是全文搜索,它真的是针对这类问题设计的,所以我先看看它。

或者在某些情况下,可能适合对数据进行非规范化并将目标字段预处理为适当的标记,然后将这些可能的搜索项添加到单独的一对多搜索表中。例如,如果我的数据总是由包含模式“AAA / BBB / CCC”的字段组成,并且我的用户正在BBB上搜索,那么我会在插入/更新时将其标记为(并在删除时删除)。这也是使用触发器而不是应用程序代码的 首选的情况之一。

我必须强调,这不是一种真正的最佳技术,只应在数据与方法匹配时使用,并且由于某种原因您不想使用全文搜索(以及数据库性能等)扫描真的是不可接受的)。它也可能会产生进一步的维护难题。

在该列上创建统计信息。 sql server 2005优化了字符串搜索,因此您可以从中受益。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top