【发布时间】:2015-12-30 01:41:19
【问题描述】:
表名[dbo].[SourceData] 有 1900 万行。
我正在针对此表运行 while 循环,并根据匹配条件将数据加载到另一个表中。 While 循环比以往任何时候都花费更长的时间。
示例代码如下。 Sourcedata 表有 seqno 这是唯一的 identity 列(主键)。名字、姓氏、地址、电子邮件地址也有单独的 NC 索引。
create table #holdscore
(
seqno bigint,
associatedseq bigint,
scrore int,
status varchar(20),
customerid varchar(30)
CONSTRAINT [PK_SourceScores]
PRIMARY KEY CLUSTERED (seqno ASC, associatedseq ASC)
)
Create table #loop
(
seqno bigint primary key clustered,
Flag varchar(1) NULL
)
Insert #loop (seqno)
select distinct TOP 1000 seqno
from [dbo].[SourceData]
order by seqno
Declare @seqno bigint
Declare @firstname Nvarchar(100)
Declare @lastname Nvarchar(100)
Declare @phonenum nvarchar(100)
Declare @emailadd Nvarchar(100)
Declare @Address Nvarchar(250)
Declare @MiddleName nvarchar(50)
Declare @CCExpYYMM nvarchar(4)
Declare @CCLastFour nvarchar(4)
While ((select count(*) from #Loop where flag is null)>0)
Begin
Select top 1 @seqno = seqno from #Loop where flag is null
Select @firstname = [FirstName],
@lastname = [LastName],
@phonenum = [PhoneNorm],
@emailadd = [EmailAddress],
@Address = [AddressNorm],
@MiddleName = [MiddleName],
@CCExpYYMM = [CCExpYYMM],
@CCLastFour = [CCLastFour]
from [dbo].[SourceData]
where seqno = @seqno
INSERT #holdscore
select
orginalseqno, associatedseq, score,
case when score >= 80 Then 'Match'
when score < 80 Then 'Review'
end as Status,
customerid
from
(select
@seqno orginalseqno, seqno as associatedseq,
customerid,
case
when [FirstName] = @firstname
and [LastName] = @lastname
and [PhoneNorm] = @phonenum
and [EmailAddress] = @emailadd
and [AddressNorm] = @Address
and [MiddleName] = @MiddleName
and [CCExpYYMM] = @CCExpYYMM
and [CCLastFour] = @CCLastFour THEN '100'
when [FirstName] = @firstname
and [LastName] = @lastname
and [PhoneNorm] = @phonenum
and [EmailAddress] = @emailadd
and [AddressNorm] = @Address
and [MiddleName] = @MiddleName
and [CCExpYYMM] = @CCExpYYMM THEN '99'
when [FirstName] = @firstname and [LastName]=@lastname and [PhoneNorm]=@phonenum and [EmailAddress]=@emailadd
and [AddressNorm] = @Address and [MiddleName] = @MiddleName and [CCLastFour] = @CCLastFour THEN '99'
WHEN [FirstName]=@firstname and [LastName]=@lastname and [PhoneNorm]=@phonenum and [EmailAddress]=@emailadd
and [AddressNorm] = @Address and [MiddleName] = @MiddleName Then '98'
WHEN [FirstName]=@firstname and [LastName]=@lastname and [PhoneNorm]=@phonenum and [EmailAddress]=@emailadd
and [AddressNorm] = @Address Then '93'
WHEN [FirstName]=@firstname and [LastName]=@lastname and [PhoneNorm]=@phonenum and [EmailAddress]=@emailadd Then '83'
WHEN [FirstName]=@firstname and [LastName]=@lastname and [PhoneNorm]=@phonenum Then '68'
WHEN [FirstName]=@firstname and [LastName]=@lastname and [EmailAddress]=@emailadd Then '63'
WHEN [FirstName]=@firstname and [LastName]=@lastname and [PhoneNorm]=@phonenum and [AddressNorm] = @Address Then '78'
WHEN [FirstName]=@firstname and [LastName]=@lastname and [EmailAddress]=@emailadd and [AddressNorm] = @Address Then '73'
WHEN [FirstName]=@firstname and [LastName]=@lastname and [AddressNorm] = @Address Then '58'
WHEN [FirstName]=@firstname and [PhoneNorm]=@phonenum and [EmailAddress]=@emailadd and [AddressNorm] = @Address and [MiddleName] = @MiddleName Then '73'
WHEN [LastName]=@lastname and [PhoneNorm]=@phonenum and [EmailAddress]=@emailadd and [AddressNorm] = @Address and [MiddleName] = @MiddleName THEN '75'
WHEN [LastName]=@lastname and [PhoneNorm]=@phonenum and [EmailAddress]=@emailadd and [AddressNorm] = @Address Then '70'
WHEN [LastName]=@lastname and [PhoneNorm]=@phonenum and [EmailAddress]=@emailadd THEN '60'
END AS Score
From [dbo].[SourceData]
)A
where A.Score is not null
OPTION (MAXDOP 8)
Update #Loop
set Flag = 'Y'
where seqno =@seqno and Flag is null
end
对于 1000 个唯一的 seqno,需要 1 个多小时才能完成。我需要将 1900 万行相互比较并将其加载到表中。请帮助我加快这个过程。这样我就可以及时加载数据。 SSIS 也可以。
【问题讨论】:
-
您是真的在使用临时表还是只是测试工具的一部分?看起来您实际上只是在尝试根据“人”信息匹配或查找潜在匹配项。
-
首先,如果您在临时表中添加了一个主键,这可能会有所帮助。但我没有立即明白你为什么在这里使用 WHILE 循环......你为什么不只是使用集合操作?
-
旁注:
varchar(1)毫无意义——它将使用 2-3 字节的存储空间来存储最多 1 个字符。对于短字符串,您应该使用char(1)- 它只占用 1 个字节并且很乐意存储您的整个字符 - 或 NULL -
你为什么不在 [FirstName]、[LastName]、[PhoneNorm] 和 [EmailAddress] 上使用 [SourceData] 内部加入 #Loop,然后将选择插入临时表中?或者将 case 查询转换为单独的 select 和 insert 查询并消除 while 循环?
标签: sql-server sql-server-2008 tsql ssis query-performance