SQL语句的优化,速度很慢,求其他方法实现
我有表a 数据为
id name
1 1002
2 1003
3 1004
表B 数据为
id namestr
1 1002|1005|
2 1004|
3 1008|
最后我想得出结构
id name flag
1 1002 1
2 1003 0
3 1004 1
简单的说,就是A表中的一个字段NAME 在B表中出现过就输出FLAG=1
我试着用标量值函数来写是可以,数据少可以,但是数据多就很慢了,有什么别的方法吗?
性能不好。很慢
对了 在表名后面加个 with(nolock)试试,比如:
a with(nolock)
b with(nolock)
防止阻塞问题。
[解决办法]
再试试函数版本的:
--1.函数
if exists(select * from sys.objects where name = 'f_splitSTR' and type = 'tf')
drop function dbo.f_splitSTR
go
create function dbo.f_splitSTR
(
@s varchar(8000), --要分拆的字符串
@split varchar(10) --分隔字符
)
returns @re table( --要返回的临时表
col varchar(1000) --临时表中的列
)
as
begin
declare @len int
set @len = LEN(@split) --分隔符不一定就是一个字符,可能是2个字符
while CHARINDEX(@split,@s) >0
begin
insert into @re
values(left(@s,charindex(@split,@s) - 1))
set @s = STUFF(@s,1,charindex(@split,@s) - 1 + @len ,'') --覆盖:字符串以及分隔符
end
insert into @re values(@s)
return --返回临时表
end
go
drop table A
drop table B
go
create table a(id int, name varchar(20))
insert into A
select 1 , '1002'
union all select 2 , '1003'
union all select 3 , '1004'
create table b(id int, namestr varchar(30))
insert into b
select 1 , '1002
[解决办法]
1005
[解决办法]
'
union all select 2 , '1004
[解决办法]
'
union all select 3 , '1008
[解决办法]
'
go
;with t
as
(
select t.col
from b with(nolock)
cross apply dbo.f_splitSTR(SUBSTRING(b.namestr,1,LEN(b.namestr)-1),'
[解决办法]
') t
)
select a.id,a.name,case when t.col IS null then 0 else 1 end flag
from a with(nolock)
left join t
on a.name = t.col
/*
idnameflag
110021
210030
310041
*/
DECLARE @a TABLE(id INT, NAME VARCHAR(20))
INSERT @a SELECT 1 ,'1002'
UNION ALL SELECT 2 ,'1003'
UNION ALL SELECT 3 ,'1004'
DECLARE @b TABLE(id INT, name VARCHAR(20))
INSERT @b SELECT 1 ,'1002
[解决办法]
1005
[解决办法]
'
UNION ALL SELECT 2 ,'1004
[解决办法]
'
UNION ALL SELECT 3 ,'1008
[解决办法]
'
SELECT a.*,SIGN(ISNULL(b.id,0)) Flag
FROM @a a LEFT JOIN @b b ON CHARINDEX('
[解决办法]
'+a.Name+'
[解决办法]
','
[解决办法]
'+b.name)>0
--Result
/*
id NAME Flag
----------- -------------------- -----------
1 1002 1
2 1003 0
3 1004 1
(所影响的行数为 3 行)
*/
SELECT 1 id ,'1002' name
into #A
UNION ALL SELECT 2 ,'1003'
UNION ALL SELECT 3 ,'1004'
SELECT 1 id ,'1002
[解决办法]
1005
[解决办法]
' name
into #B
UNION ALL SELECT 2 ,'1004
[解决办法]
'
UNION ALL SELECT 3 ,'1008
[解决办法]
'
SELECT a.*,case when b.id is null then 0 else 1 end Flag
FROM #A a LEFT JOIN #B b ON CHARINDEX(a.Name,b.name)>0