我有一张包含 117000 条左右记录的表。我需要执行一个搜索,检查给定字符串模式的 3 个单独字段。
我的where子句如下:
field1 LIKE '%' + @DESC + '%'
OR field2 LIKE '%' + @DESC + '%'
OR field3 LIKE '%' + @DESC + '%'
无论输入如何,这似乎都需要大约 24 秒...
有一个更好的方法吗?少于 10(或 5!)秒会更可取。
谢谢你的帮助。
我有一张包含 117000 条左右记录的表。我需要执行一个搜索,检查给定字符串模式的 3 个单独字段。
我的where子句如下:
field1 LIKE '%' + @DESC + '%'
OR field2 LIKE '%' + @DESC + '%'
OR field3 LIKE '%' + @DESC + '%'
无论输入如何,这似乎都需要大约 24 秒...
有一个更好的方法吗?少于 10(或 5!)秒会更可取。
谢谢你的帮助。
使用全文搜索和包含。LIKE 在字段中间搜索时无法优化,即。当 LIKE 表达式以 '%' 开头时,它总是会进行全表扫描。
每当您使用通配符开始 LIKE 搜索时,您就是在进行扫描。除非您可以缩小搜索条件以包括第一个字符(这可能不可行),否则您需要求助于全文搜索。
你真的需要从通配符开始吗?为什么?通常,您可以强制用户至少输入第一个字符。我提出这一点是因为一些开发人员只是将通配符用作一种习惯,而不是因为有要求。在大多数情况下,用户将能够键入第一个字符,除非该文件存储了长字符串(例如官方机场名称)。否则,您确实需要使用全文索引,尽管如果您最后不需要通配符,KM 的反向技巧非常酷。
如果您可以避免做性能破坏的事情,那么就这样做。
虽然我同意全文索引将是最佳解决方案的公认答案,并且绝不提倡在必须执行领先的通配符搜索时使用它们,但可以采取一些潜在的步骤来降低它们的性能坏的。
Kalen Delaney 在“ Microsoft SQL Server 2008 Internals ”一书中说:
当 SQL Server 必须查看字符串中的几乎所有字符时,排序规则会产生巨大的影响。例如,请看以下内容:
SELECT COUNT(*) FROM tbl WHERE longcol LIKE '%abc%'
二进制排序规则的执行速度可能比非二进制 Windows 排序规则快 10 倍或更多。对于
varchar
数据,使用 SQL 排序规则的执行速度比使用 Windows 排序规则快七到八倍。
怎么样
field1 + field2 + field3 LIKE '%' + @DESC + '%'
或者
CONTAINS(field1 + field2 + field3, @DESC)
我尝试了一种可能的解决方案。在此解决方案之前,甚至查询都没有返回结果并导致连接超时错误。
我的查询有日期过滤器和其他条件。所有其他条件都类似于搜索。一个列关键字在 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
它对我有用。
如果您不能使用 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