Ich habe eine Situation, in der ich Tausende von Datensätzen von einem Versuchbar in eine Datenbanktabelle verarbeiten und schließlich einfügen muss. Vor jeder Einfügung muss ich sicherstellen, dass die Bedingungen erfüllt sind und direkt nach jeder Einfügung muss ich eine zweite Tabelle in meiner Datenbank aktualisieren. Mein Problem ist, dass es derzeit etwa 25 Minuten dauert, um die Abfrage auszuführen, und ich möchte diese Zeit drastisch reduzieren, damit meine Anwendung reaktionsfähiger wird. Wie kann ich das bitte tun?Optimieren von T-SQL Einfügen - testable, CTEs, WHILE-Schleifen
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
Ich glaube, das ist der Ort, an dem der Großteil des Problems liegt.
WHILE @rownumber < @rowcounter set @rownumber BEGIN = @rownumber + 1 - die Variablen DEKLARIEREN @record_no als BIGINT DECLARE- @phone_name VARCHAR (30) DECLARE- @messagepriority als INTEGER DECLARE- @phone_number VARCHAR (30) DECLARE @phone_id BIGINT DEKLARIEREN @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
Legen Sie fest, was in Ihrem (langen) geposteten Code die Verlangsamung verursacht, und wir könnten Ihnen vielleicht helfen. –
Die Verlangsamung beginnt beim WHILE LOOP. Genau davor läuft der Code ungefähr 0,16 Sekunden. Sobald es die While-Schleife erreicht, erhöht sich die Verarbeitungszeit um 25 Minuten. – Kobojunkie