我有一张117000左右的记录表。我需要执行搜索,检查给定字符串模式的3个单独字段。
我的where子句如下:
field1 LIKE '%' + @DESC + '%'
OR field2 LIKE '%' + @DESC + '%'
OR field3 LIKE '%' + @DESC + '%'
无论输入如何,这似乎需要大约24秒......
有更好的方法吗?小于10(或5!)秒会更好。
感谢您的帮助。
答案 0 :(得分:13)
使用全文搜索和CONTAINS。在字段中间搜索时无法优化LIKE,即。当LIKE表达式以'%'开头时,它将始终执行全表扫描。
答案 1 :(得分:2)
无论何时使用通配符开始LIKE搜索,您都在进行扫描。除非您可以缩小搜索条件以包含第一个字符(这可能不可行),否则您需要求助于全文搜索。
答案 2 :(得分:1)
你真的需要从通配符开始吗?为什么?通常,您可以强制用户至少输入第一个字符。我提出这个问题是因为一些开发人员只是使用通配符作为习惯而不是因为有需求。在大多数情况下,除非文件存储长字符串(例如官方机场名称),否则用户将能够键入第一个字符。否则你真的需要使用全文索引,尽管如果你最后不需要通配符,KM的反向技巧是非常酷的。
如果你可以避免做性能杀戮,那就这样做。
答案 3 :(得分:1)
虽然我同意已接受的答案,即全文索引将是最佳解决方案,并且绝不提倡使用领先的通配符搜索(如果必须执行),那么是潜在的步骤可以用来降低他们的表现。
凯伦德莱尼在“Microsoft SQL Server 2008 Internals”一书中说:整理可以产生巨大的差异 什么时候SQL Server几乎要看 字符串中的所有字符。对于 例如,请看以下内容:SELECT COUNT(*) FROM tbl WHERE longcol LIKE '%abc%'
使用二进制排序规则可以比非二进制Windows排序规则快10倍或更多。使用
varchar
数据时,SQL排序规则的执行速度比Windows排序规则快7到8倍。
答案 4 :(得分:0)
怎么样
field1 + field2 + field3 LIKE '%' + @DESC + '%'
或
CONTAINS(field1 + field2 + field3, @DESC)
答案 5 :(得分:0)
我尝试了一种可能的解决方案。在此解决方案之前,即使查询未返回结果并导致连接超时错误。
我的查询是日期过滤器和其他条件。所有其他标准都像搜索。一列关键字在ntext列上搜索'%abc%',它正在进行全表扫描。
解决方案:
将查询分为两部分。 1)CTE的第一部分(Common Table Express)2)在CTE上应用所有搜索标准。
WITH SearchData(Column1,Column2,Column3,Column4,........)
AS
(
SELECT Column1,Column2,Column3,Column4,...........
FROM myTable1 WITH(NOLOCK)
INNER JOIN MyTable2 WITH(NOLOCK)
ON MyTable1.id = MyTable2.Id
WHERE (MyTable1.CreationTime >= '2014-04-27' AND MyTable1.CreationTime <= '2014-05-01')
)
SELECT DISTINCT top 250 Column1,Column2,Column3,Column4
FROM SearchData
WHERE (ISNULL(Column1,'') LIKE @Column1 +'%' OR @Column1 IS NULL)
and (Column2 LIKE @Column2+ '%' OR @Column2 IS NULL)
...
...
...
...
AND (Column10 like '%'+@Column10+'%' or @Column10 IS NULL)
AND @Column1+@Column2+@Column3+........@Column10 <> ''
ORDER BY [CreationTime] DESC
它对我有用。
答案 6 :(得分:0)
如果您无法使用FullTextSearch,您可以将速度提高10倍。下一步:
1添加计算字段:
alter table TableName
add CalculatedColumnName as upper(Column1 + '|' + Column2...) collate Latin1_General_100_Bin2
persisted;
2为计算字段添加索引:
create nonclustered index IDX_TableName_CalculatedColumnName
on TableName(CalculatedColumnName);
3更改您的查询文字
select count(*)
from TableName
where CalculatedColumnName like '%' + upper(@ParameterValue) + '%' collate Latin1_General_100_Bin2
来源:http://aboutsqlserver.com/2015/01/20/optimizing-substring-search-performance-in-sql-server