繁体   English   中英

SQL Server - 使用临时表优化存储过程

[英]SQL Server - optimise the stored procedure by using temp table

我想用 UTC 日期更新我所有的日历开始和结束日期。 我还必须考虑夏令时,所以我创建了一个临时表并插入了过去 10 年的所有夏令时。 但我不确定如何在更新语句中使用临时表值。 到目前为止用 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

我有大量数据,我不确定这是否是正确的方法。 有人可以建议我如何优化更新语句,请指教。

创建临时表后,查询将类似于

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 )

对于 else 条件,以防万一

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 )

应避免 where 中的 IN 子句,必须将其替换为一个存在子句。 将这些硬编码的 id 放入临时表 #selected_id 并使用exists 子句,将提高性能。

如果数据很大,请尝试批量运行这些更新(使用 while 循环和事务)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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