处理这个复杂的LIKE语句的更有效/更优雅的方式?

问题描述 投票:0回答:2

我需要一些帮助尝试使这个LIKE声明更优雅和高效。它执行我期望它的方式,但它很慢,即使在小数据集上也是如此。我在win 10机器上使用带有SSMS 2017的SQL-Server 2016。提前致谢!

where (a.Description like '% ' + @event + ' %'  
        or a.Description like '% ' + @event + '.'   
        or a.Description like '% ' + @event + '.%'  
        or a.Description like '% ' + @event + ',%'  
        or a.Description like '% ' + @event + ';%'
        or a.Description like '%'  + @event + '/%'
        or a.Description like '%/' + @event + '%'
        or a.Description like '% ' + @event 
        or a.Description like @event + ' %' 
        or a.Description like @event 
        )

@event只是像'死亡'或'绊倒'的varchar。如果你有更好的方法,无论如何,请教我!

sql sql-server regex sql-like
2个回答
4
投票

T-SQL支持LIKE中的字符类,因此您可以简化:

where (a.Description like '%[ /]' + @event + '[ .,;/]%'
        or a.Description like '%[ /]' + @event
        or a.Description like @event + '[ .,;/]%'
        or a.Description like @event 
        )

如果您愿意接受任何非字母分隔符(数字有关),您可以执行以下操作:

where (a.Description like '%[^a-z0-9]'+@event+'[^a-z0-9]%'
       or a.Description like @event+'[^a-z0-9]%'
       or a.Description like '%[^a-z0-9]'+@event
       or a.Description like @event
       )

1
投票

假设描述是非索引列,一种使其可能更快的方法是从原始描述字符串中创建较小的字符串,并对这些较小的字符串进行比较。

这很好,直到描述栏中的数据较少。

如果您可以预先存储和索引存储的数据列,您可以尝试动态如下

我替补标记,发现N = 13后,%string%的表现变坏了

if exists (select object_id('t') )
drop table t
create table t (description varchar(max));

insert into t  values
('Implemantion of the CR systems at dealership level for understanding of the customer concern & faster resolution'),
('Trend analysis for Customer Complaint Ratio at Regional / Zonal / Area level both for Sales and Service operations');

declare @counter int
set @counter=1

WHILE @counter<15
begin
insert into t
select * from t
set @counter=@counter+1
end
declare @start datetime,@end1 datetime,@end2 datetime


declare @lookingfor varchar(100)
set @lookingfor ='level'

select 
description,
cast(substring(t.description,N,LEN(@lookingfor)) as varchar(100)) as d into #t from t
outer apply
(select top (select LEN(t.description)-LEN(@lookingfor)+1)
 row_number() over(order by (select null)) N
  from sys.objects s1 cross join sys.objects s2
)T1

CREATE NONCLUSTERED INDEX IDX_C_temp_d ON #t(d)

set @start=getdate()
select count(distinct description) from t
where description like '%'+@lookingfor+'%'

select @end1=getdate()

select count(distinct description) from #t  where d like @lookingfor

select @end2=getdate()

select datediff(ss,@start,@end1)

select datediff(ss,@end1,@end2)

select @start,@end1,@end2

drop table #t

PS:您需要对解决方案进行基准测试。

© www.soinside.com 2019 - 2024. All rights reserved.