私は、処理が必要な状況があり、最後に誘惑可能なレコードをデータベーステーブルに挿入する必要があります。各挿入の前に、条件が満たされていることを確認し、各挿入の直後に、データベースの2番目のテーブルを更新する必要があります。私の問題は、現在、クエリを実行するのに約25分かかり、私のアプリケーションがより敏感になるように大幅に時間を短縮したいと思っています。どうしたらいいですか?T-SQL Insert-temptable、CTEs、WHILEループの最適化
DECLARE @rowcounter as INTEGER
CREATE TABLE #temporary_phonetable
(
rownumber int not null identity(1,1),
record_no BIGINT,
phone_name BIGINT,
phone_number Varchar(25) not null ,
responsemessage Varchar(200) not null ,
messagepriority Varchar(14) not null ,
phone_id BIGINT,
AD_show BIGINT,
power_show Varchar(400),
service_provider VARCHAR(30),
Phone_flag VARCHAR(30),
questionMessage BIGINT,
PRIMARY KEY (phone_id, phone_number, rownumber)
,UNIQUE (questionMessage, record_no, rownumber)
)
--GET PHONE DATA
--if phone numbers are sent in from the client, then we want to process those instead
IF (((@listofphones IS NULL OR LEN(@listofphones) <1) AND LEN(@peoplegroups) >0) )
BEGIN
--NO PHONENUMBER BUT THERE ARE GROUPS AVAILABLE
INSERT INTO #temporary_phonetable(phone_name, phone_number, messagepriority, phone_id, AD_show, power_show, responsemessage)
SELECT n.phone_name, n.phone_number,u.messagepriority, n.phone_id , u.AD_show, u.power_show , CASE @includegreetings WHEN 1 THEN LTRIM(RTRIM(phone_name)) + @responsemessages
ELSE @responsemessages END as text_message
FROM user u WITH(NOLOCK)
INNER JOIN Phonenumbers n WITH(NOLOCK) ON n.user_no = u.user_no
INNER JOIN PeopleGroupRelations g ON g.phone_id=n.phone_id
INNER JOIN (Select items FROM Split(@peoplegroups, @listofphonesdelimiter)) gg ON g.group_no = gg.items
WHERE [email protected]
AND n.status=''active''
SET @rowcounter = @@ROWCOUNT
END
ELSE IF (LEN(@listofphones) >1 AND LEN(@peoplegroups) >0)
BEGIN
--PHONENUMBER AND GROUPS
INSERT INTO #temporary_phonetable(phone_name, phone_number, messagepriority, phone_id, AD_show, power_show, responsemessage)
SELECT n.phone_name, n.phone_number,u.messagepriority, n.phone_id , u.AD_show, u.power_show , CASE @includegreetings WHEN 1 THEN LTRIM(RTRIM(phone_name)) + @responsemessages
ELSE @responsemessages END as text_message
FROM Split(@listofphones, ''|'') s
INNER JOIN PhoneNumbers n WITH(NOLOCK) ON n.phone_number = s.items
INNER JOIN User u WITH(NOLOCK) ON n.user_no =u.user_no
INNER JOIN PeoplegroupRelations g ON g.phone_id=n.phone_id
INNER JOIN (Select items FROM Split(@peoplegroups, @listofphonesdelimiter)) gg ON g.group_no = gg.items
WHERE [email protected]
AND n.status=''active''
SET @rowcounter = @@ROWCOUNT
END
ELSE IF (LEN(@listofphones) >1 AND LEN(@peoplegroups) >0)
BEGIN
--PHONENUMBER AND NO GROUPS
INSERT INTO #temporary_phonetable(phone_name, phone_number, messagepriority, phone_id, AD_show, power_show, responsemessage)
SELECT n.phone_name, n.phone_number,u.messagepriority, n.phone_id , u.AD_show, u.power_show , CASE @includegreetings WHEN 1 THEN LTRIM(RTRIM(phone_name)) + @responsemessages
ELSE @responsemessages END as text_message
FROM Split(@listofphones, ''|'') s
INNER JOIN PhoneNumbers n WITH(NOLOCK) ON n.phone_number = s.items
INNER JOIN User u WITH(NOLOCK) ON n.user_no =u.user_no
INNER JOIN PeopleGroupRelations g ON g.phone_id=n.phone_id
INNER JOIN (Select items FROM Split(@peoplegroups, @listofphonesdelimiter)) gg ON g.group_no = gg.items
WHERE [email protected]
AND n.status=''active''
SET @rowcounter = @@ROWCOUNT
END
ELSE
BEGIN
-- NO PHONENUMBER NO GROUP --- IE. SEND TO ALL PHONE NUMBERS
INSERT INTO #temporary_phonetable(phone_name, phone_number, messagepriority, phone_id, AD_show, power_show,responsemessage)
SELECT n.phone_name, n.phone_number,u.messagepriority, n.phone_id , u.AD_show, u.power_show , CASE @includegreetings WHEN 1 THEN LTRIM(RTRIM(phone_name)) + @responsemessages
ELSE @responsemessages END as text_message
FROM User u
INNER JOIN PhoneNumbers n ON n.user_no = u.user_no
WHERE
n.status=''active''
AND [email protected]
SET @rowcounter = @@ROWCOUNT
END
IF(@rowcounter>0)
BEGIN
DECLARE @service_provider as Varchar(30)
DECLARE @PhoneType as Varchar(30)
IF (LOWER(RTRIM(LTRIM(@sendresponseswhen))) ='now')
BEGIN
SET @dateresponsessent = GETDATE()
END
DECLARE @rownumber int
DECLARE @power_show BIT
DECLARE @AD_show BIT
set @rownumber = 0
WHILE @rownumber < @rowcounter
BEGIN
set @rownumber = @rownumber + 1
-- THE VARIABLES
DECLARE @record_no as BIGINT
DECLARE @phone_name VARCHAR(30)
DECLARE @messagepriority as INTEGER
DECLARE @phone_number VARCHAR(30)
DECLARE @phone_id BIGINT
DECLARE @questionMessage BIGINT
SELECT
@phone_name = n.phone_name, @phone_number =n.phone_number, @messagepriority =n.messagepriority, @phone_id=n.phone_id ,
@AD_show=n.AD_show, @power_show=n.power_show
FROM
#temporary_phonetable n WITH(NOLOCK)
WHERE n.rownumber = @rownumber
SET @record_no = AddMessageToQueue(@phone_number, @responsemessages, @dateresponsessent, @savednames, @userid, un.messagepriority, @responsetype,
un.AD_show, un.power_show, @service_provider, @PhoneType)
If(@questionid > 0)
BEGIN
SET @questionMessage = AddQuestionMessage(@questionid,@phone_id, @record_no, DATEADD(d, 30, GETDATE()))
END
UPDATE #temporary_phonetable SET record_no = @record_no, [email protected] WHERE phone_number = @phone_number AND rownumber = @rownumber
END
IF(@power_show >0)
BEGIN
SET @responsemessages = @responsemessages + dbo.returnPoweredBy()
END
IF(@AD_show > 0)
BEGIN
SELECT @responsemessages = @responsemessages + CASE
WHEN (LEN(@responsemessages) + 14)< 160 THEN dbo.returnAD(@responsemessages)
ELSE '''' END
END
RETURN @rowcounter
END
私はこれが問題の大部分が存在する場所だと考えています。
@rowcounterセット@rownumberをBEGIN < @rownumberWHILE = @rownumber + 1 - 変数がINTEGER DECLAREの@phone_numberとしてBIGINT DECLAREの@phone_name VARCHAR(30) DECLAREの@messagepriorityとして@record_no DECLARE VARCHAR(30) DECLARE @phone_id BIGINT DECLARE @questionMessage BIGINT
SELECT
@phone_name = n.phone_name, @phone_number =n.phone_number, @messagepriority =n.messagepriority, @phone_id=n.phone_id ,
@AD_show=n.AD_show, @power_show=n.power_show
FROM
#temporary_phonetable n WITH(NOLOCK)
WHERE n.rownumber = @rownumber
SET @record_no = AddMessageToQueue(@phone_number, @responsemessages, @dateresponsessent, @savednames, @userid, un.messagepriority, @responsetype,
un.AD_show, un.power_show, @service_provider, @PhoneType)
If(@questionid > 0)
BEGIN
SET @questionMessage = AddQuestionMessage(@questionid,@phone_id, @record_no, DATEADD(d, 30, GETDATE()))
END
UPDATE #temporary_phonetable SET record_no = @record_no, [email protected] WHERE phone_number = @phone_number AND rownumber = @rownumber
END
あなたの(長い)投稿されたコードで何が減速の原因となっているかを特定し、私たちが助けることができるかもしれません。 –
低速はWHILE LOOPから始まります。その直前に、コードは約0.16秒実行されます。 Whileループに当たったら、処理時間が25分増加します – Kobojunkie