简体   繁体   中英

SQL Server - optimise the stored procedure by using temp table

I want to update all of my calendar start and end date with the UTC dates. I also have to consider the daylight saving dates so I created a temp table and inserted all the daylight saving dates for last 10 years. But I am not sure how can I use the temp table values in my update statement. The code written so far in SP:

CREATE TABLE #DTSDates (
    StartDate datetime,
    EndDate datetime
);

INSERT INTO #DTSDates VALUES('2011-03-13 02:00:00.000', '2011-11-06 02:00:00.000');
INSERT INTO #DTSDates VALUES('2012-03-11 02:00:00.000', '2012-11-04 02:00:00.000');
INSERT INTO #DTSDates VALUES('2013-03-10 02:00:00.000', '2013-11-03 02:00:00.000');
INSERT INTO #DTSDates VALUES('2014-03-09 02:00:00.000', '2014-11-02 02:00:00.000');
INSERT INTO #DTSDates VALUES('2015-03-08 02:00:00.000', '2015-11-01 02:00:00.000');
INSERT INTO #DTSDates VALUES('2016-03-13 02:00:00.000', '2016-11-06 02:00:00.000');
INSERT INTO #DTSDates VALUES('2017-03-12 02:00:00.000', '2017-11-05 02:00:00.000');
INSERT INTO #DTSDates VALUES('2018-03-11 02:00:00.000', '2018-11-04 02:00:00.000');
INSERT INTO #DTSDates VALUES('2019-03-10 02:00:00.000', '2019-11-03 02:00:00.000');
INSERT INTO #DTSDates VALUES('2020-03-08 02:00:00.000', '2020-11-01 02:00:00.000');


UPDATE Calendar
SET StartDate = CASE   
                    WHEN (StartDate BETWEEN '2011-03-13 02:00:00.000' and '2011-11-06 02:00:00.000') 
                    OR (StartDate BETWEEN '2012-03-11 02:00:00.000' and '2012-11-04 02:00:00.000')
                    OR (StartDate BETWEEN '2013-03-10 02:00:00.000' and '2013-11-03 02:00:00.000')
                    OR (StartDate BETWEEN '2014-03-09 02:00:00.000' and '2014-11-02 02:00:00.000')
                    OR (StartDate BETWEEN '2015-03-08 02:00:00.000' and '2015-11-01 02:00:00.000')
                    OR (StartDate BETWEEN '2016-03-13 02:00:00.000' and '2016-11-06 02:00:00.000')
                    OR (StartDate BETWEEN '2017-03-12 02:00:00.000' and '2017-11-05 02:00:00.000')
                    OR (StartDate BETWEEN '2018-03-11 02:00:00.000' and '2018-11-04 02:00:00.000')
                    OR (StartDate BETWEEN '2019-03-10 02:00:00.000' and '2019-11-03 02:00:00.000')
                    OR (StartDate BETWEEN '2020-03-08 02:00:00.000' and '2020-11-02 02:00:00.000')
                THEN DATEADD(MINUTE, @Offset + 60, StartDate)               
                ELSE DATEADD(MINUTE, @Offset, StartDate) END,       
EndDate = CASE   
                WHEN (EndDate BETWEEN '2011-03-13 02:00:00.000' and '2011-11-06 02:00:00.000') 
                OR (EndDate BETWEEN '2012-03-11 02:00:00.000' and '2012-11-04 02:00:00.000')
                OR (EndDate BETWEEN '2013-03-10 02:00:00.000' and '2013-11-03 02:00:00.000')
                OR (EndDate BETWEEN '2014-03-09 02:00:00.000' and '2014-11-02 02:00:00.000')
                OR (EndDate BETWEEN '2015-03-08 02:00:00.000' and '2015-11-01 02:00:00.000')
                OR (EndDate BETWEEN '2016-03-13 02:00:00.000' and '2016-11-06 02:00:00.000')
                OR (EndDate BETWEEN '2017-03-12 02:00:00.000' and '2017-11-05 02:00:00.000')
                OR (EndDate BETWEEN '2018-03-11 02:00:00.000' and '2018-11-04 02:00:00.000')
                OR (EndDate BETWEEN '2019-03-10 02:00:00.000' and '2019-11-03 02:00:00.000')
                OR (EndDate BETWEEN '2020-03-08 02:00:00.000' and '2020-11-02 02:00:00.000')
            THEN DATEADD(MINUTE, @Offset + 60, EndDate)             
            ELSE DATEADD(MINUTE, @Offset, EndDate) END  
WHERE CalendarId IN (1,3,4,7,90,34,56,78,23) -- too many ids

I have a large number of data and I am not sure if this is the right way to go about it. Can someone suggest how can I optimize the update statement, please advise.

Once you created the temporary table , query will be like

Update Calendar
Set StartDate = DATEADD(MINUTE, @Offset + 60, StartDate) ,endate= xyz
From Calendar  cal
Join #dtsdates dts
on cal.startdate >= dts.startdate and cal.startdate <=dts.enddate 
WHERE exists (Select id from #selected_id sel where sel.id = cal.id )

For the else condition in case

Update Calendar
Set StartDate = DATEADD(MINUTE, @Offset , StartDate) ,endate= xyz
From Calendar  cal
Join #dtsdates dts
on cal.startdate <= dts.startdate and cal.startdate >=dts.enddate 
WHERE exists (Select id from #selected_id sel where sel.id = cal.id )

IN clause in where should be avoided and it must be replaced by a exists clause. Put these hard coded ids into a temporary table #selected_id and use a exists clause, will improve performance.

If the data is huge, try running these update in batches (using a while loop and a transaction)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM