在线更新SQL Server千万级记录的大表

目录

问题描述

某表含有2000万+记录行,80+字段,10+索引,单表含索引数据达27GB

由于某些原因,导致此表中的3个字段需进行更新,同时要求停机时间尽可能的短,相关sql如下:

--停机更新3个字段需耗时80分钟
UPDATE big_table SET P1 = 'N', P2 = 'N', P3 = 'N'

问题分析

由于停机执行上述update语句需耗时80分钟,因此考虑使用在线更新方案。分析表的字段内容与含义,发现表存在自增列id。

我们重新理解聚集索引表与堆表,评估update语句对单表的影响:在SQL Server中,执行update语句可能产生阻塞。这里我们使用高频率的update小批量高频度的进行更新可以有效降低阻塞的时间。

解决办法

创建一个视图,并通过job的方式高频度的更新视图上的这3个字段,同时检查更新的执行计划是否通过索引。

详细代码如下:
– 创建一个视图与一个临时表

--创建一个含主键与3个字段内容的视图
create view vv as SELECT Id, P1, P2, P3 FROM big_table GO --创建一个记录更新的临时表 create table tmp_values ( ctime datetime primary key default getdate(), n bigint not null ) --插入初始 insert tmp_values (n) values(0) 
  • 为了降低SQL Server的阻塞,我们将更新sql代码修改成一个存储过程,然后通过Job去定期执行
--创建更新的存储过程
CREATE PROCEDURE updatevv as begin DECLARE @i bigint DECLARE @num bigint --每次更新1500条记录 set @num=1500 set @i=(select top 1 n from tmp_values order by ctime desc) insert tmp_values (n) values(@num+@i) update vv set P1='N', P2='N', P3='N' where id<@i+@num and id>=@i end

注意:这里并没有使用@@rowcount,是由于这个表的内容决定的。

参考资料

1. SQL Server 2008 Locking
http://blogs.technet.com/b/josebda/archive/2009/03/19/sql-server-2008-locking.aspx

    原文作者:SQL
    原文地址: https://blog.csdn.net/wstoneh01/article/details/50631152
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞