我面临一个大问题,下面的存储过程需要花费大量时间来执行。请帮我找到以下存储过程的问题。
我们需要将excel中的批量订阅者列表插入到数据库中。但是只有60个订阅者在一分钟内插入到db中。
请帮我解决这个问题。
USE [SMS]
GO
/****** Object: StoredProcedure [dbo].[SP_ProcessFile] Script Date: 01/30/2015 12:56:59 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SP_ProcessFile]
@JobCode varchar(25)
WITH RECOMPILE
AS
declare
@jobCode1 Varchar(50),
@count int,@Code varchar(50),@Name [varchar](50),@Date Datetime,@Status int,
@i int,@EUCount int,@SubCount int,
@Add1 nvarchar(3000) ,
@Add2 nvarchar(500) ,
@Add3 nvarchar(500)
,@refdate [varchar](50) ,
@reference [varchar](50) ,
@Joined [varchar](50),
@Joinmonth [nvarchar](50),
@Activated [varchar](50),
@ActivMonth [nvarchar](50),
@Center [varchar](50) ,
@Region [varchar](50) ,
@Area [varchar](50) ,
@Modem [varchar](50) ,
@Adomstatus [varchar](50)
, @AddCode [varchar](50)
set @i = 1
Set @jobCode1 =@JobCode
BEGIN
SET NOCOUNT ON
Set @Status = (Select Distinct(status) from TSMST1005 where Jobcode = @jobCode1)
if (@Status = 0)
begin
Select '1' as res
end
else
begin
CREATE TABLE #tblSMS(pID int identity(1,1),
[Reference] [nvarchar](50) NULL,
[Date] [varchar](50) NOT NULL,
[Code] [nvarchar](50) NULL,
[Subname] [varchar](500) NULL,
[Address1] [nvarchar](3000) NULL,
[Address2] [nvarchar](500) NULL,
[Address3] [nvarchar](500) NULL,
[Joined] [varchar](50) NULL,
[Joinmonth] [varchar](50) NULL,
[Activated] [varchar](50) NULL,
[ActivMonth] [nvarchar](50) NULL,
[Center] [varchar](50) NULL,
[Region] [varchar](50) NULL,
[Area] [varchar](50) NULL,
[Modem] [varchar](50) NULL,
[Adomstatus] [varchar](50) NULL,
[RefDate] [varchar](50) NOT NULL)
insert into #tblSMS
SELECT Reference,[Date],
Code,Subname ,Address1 ,Address2 ,Address3 ,
Joined , Joinmonth ,Activated, ActivMonth ,
Center,Region,Area,Modem,Adomstatus ,refdate FROM TSMST1005 where jobcode = @jobCode1 and Status =1
WHILE @i <= (SELECT COUNT(*) FROM #tblSMS)
BEGIN
SELECT
@Code =Code,
@Name = Subname,
@Date =[Date],
@Add1 =Address1 ,
@Add2 =Address2 ,
@Add3= Address3,
@reference =Reference ,
@Joined = Joined,
@Joinmonth =Joinmonth,
@Activated =Activated,
@ActivMonth =ActivMonth,
@Center = Center,
@Region = Region,
@Area= Area,
@Modem = Modem ,
@Adomstatus =Adomstatus,
@refdate = RefDate
From #tblSMS where pID = @i
Insert into TCMST5001 (CompanyCode , Address1,Address2 ,Address3 ,CreatedDate ,Status) values('001',@Add1 ,@Add2,@Add3,GETDATE(),1)
Set @count = SCOPE_IDENTITY()
Set @AddCode = 'ADD' + Cast(@count As Varchar(10))
Update TCMST5001 Set Code =@AddCode Where AddressID =@count
Set @EUCount = (Select COUNT(*) from TCCOM0005 where EnterpriseUnitCode = @Center)
if (@EUCount = 0)
Begin
Insert into TCCOM0005(AddressCode,CompanyCode,EnterpriseUnitCode,EnterpriseUnitName,Status) values(@count ,'001',@Center,@Center ,1)
END
Set @SubCount = (Select COUNT(*) from TSMST1001 where Subscriber = @Code)
if (@SubCount =0)
begin
Insert into TSMST1001(ActivationDate ,refdate , Address ,AlternateName ,Area ,Region ,Subscriber,Name ,date ,CreatedDate ,EnterpriseUnit ,Status)
values(@Activated,@refdate ,@count ,@Name,@Area,@Region,@Code,@Name ,@Joined ,GETDATE(),@Center,@Adomstatus)
end
Insert into TSMST1003 (Device ,CreatedDate ,Subscriber,StartDate) values
(@Modem,GETDATE(),@Code,@Activated)
SET @i = @i + 1
Update TSMST1005 Set Status = 0 where Jobcode = @jobCode1
Select '3' as res
END
END
Drop table #tblSMS
end
答案 0 :(得分:0)
很难给你100%的工作程序。但是,您的问题是您要逐行插入记录。而不是这样做,你需要在BULK中插入记录。那会更快。有重写程序。您仍然需要通过相同的逻辑重写2个插入。当然可能存在缺陷,因为它完全未经测试。无论如何,我们在这里:
USE [SMS]
GO
/****** Object: StoredProcedure [dbo].[SP_ProcessFile] Script Date: 01/30/2015 12:56:59 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SP_ProcessFile] @JobCode VARCHAR(25)
WITH RECOMPILE
AS
BEGIN
SET NOCOUNT ON
SET @Status = ( SELECT TOP 1 status
FROM TSMST1005
WHERE Jobcode = @jobCode
)
IF ( @Status = 0 )
BEGIN
SELECT '1' AS res
END
ELSE
BEGIN
CREATE TABLE #tblSMS
(
pID INT IDENTITY(1, 1) ,
[Reference] [NVARCHAR](50) NULL ,
[Date] [VARCHAR](50) NOT NULL ,
[Code] [NVARCHAR](50) NULL ,
[Subname] [VARCHAR](500) NULL ,
[Address1] [NVARCHAR](3000) NULL ,
[Address2] [NVARCHAR](500) NULL ,
[Address3] [NVARCHAR](500) NULL ,
[Joined] [VARCHAR](50) NULL ,
[Joinmonth] [VARCHAR](50) NULL ,
[Activated] [VARCHAR](50) NULL ,
[ActivMonth] [NVARCHAR](50) NULL ,
[Center] [VARCHAR](50) NULL ,
[Region] [VARCHAR](50) NULL ,
[Area] [VARCHAR](50) NULL ,
[Modem] [VARCHAR](50) NULL ,
[Adomstatus] [VARCHAR](50) NULL ,
[RefDate] [VARCHAR](50) NOT NULL
)
INSERT INTO #tblSMS
SELECT Reference ,
[Date] ,
Code ,
Subname ,
Address1 ,
Address2 ,
Address3 ,
Joined ,
Joinmonth ,
Activated ,
ActivMonth ,
Center ,
Region ,
Area ,
Modem ,
Adomstatus ,
RefDate
FROM TSMST1005
WHERE jobcode = @jobCode1
AND Status = 1
WHILE @i <= ( SELECT COUNT(*)
FROM #tblSMS
)
BEGIN
DECLARE @minPK INT;
SELECT @minPK = MAX(AddressID ) FROM TCMST5001; -- I believe that it is identity column. If not change it to the proper one
INSERT INTO TCMST5001
( CompanyCode ,
Address1 ,
Address2 ,
Address3 ,
CreatedDate ,
Status
)
SELECT '001', Address1, Address2, Address3, GETDATE(), 1 FROM #tblSMS;
SET @AddCode = 'ADD' + CAST(@count AS VARCHAR(10))
UPDATE TCMST5001
SET Code = 'ADD' + CAST(AddressID AS VARCHAR(10))
WHERE AddressID > @minPK ;
INSERT INTO TCCOM0005
SELECT ee.cnt, t.center, t.Center, 1
FROM #tblSMS t
CROSS APPLY ( SELECT COUNT(*) AS cnt FROM TCCOM0005 e WHERE e.EnterpriseUnitCode = t.Center) ee
WHERE ee.cnt > 0
-- THE SAME LOGIC MUST BE DONE WITH THESE 2 INSERTS
SET @SubCount = ( SELECT COUNT(*)
FROM TSMST1001
WHERE Subscriber = @Code
)
IF ( @SubCount = 0 )
BEGIN
INSERT INTO TSMST1001
( ActivationDate ,
refdate ,
Address ,
AlternateName ,
Area ,
Region ,
Subscriber ,
Name ,
date ,
CreatedDate ,
EnterpriseUnit ,
Status
)
VALUES ( @Activated ,
@refdate ,
@count ,
@Name ,
@Area ,
@Region ,
@Code ,
@Name ,
@Joined ,
GETDATE() ,
@Center ,
@Adomstatus
)
END
INSERT INTO TSMST1003
( Device ,
CreatedDate ,
Subscriber ,
StartDate
)
VALUES ( @Modem ,
GETDATE() ,
@Code ,
@Activated
)
UPDATE t
FROM TSMST1005 t
SET Status = 0
JOIN #tblSMS tmp
ON tmp.jobCode1 = t.Jobcode
SELECT '3' AS res
END
END
DROP TABLE #tblSMS
END
答案 1 :(得分:0)
一些提示将是。避免在每一步都这样做。
SELECT COUNT(*) FROM #tblSMS
而是将计数值分配给局部变量,并检查i是否相同。
此外,您经常从这些表中选择值(TCCOM0005,TSMST1001,TSMST1003),最好检查这些表是否具有正确的索引。