[英]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.