大数据量表中,增加一个NOT NULL的新列
这次,发布清洗列表功能,需要对数据库进行升级。MailingList表加个IfCleaning字段,所有的t_User*表加个IfCleaned字段。
脚本如下
对所有的t_User表执行
alter table t_User** add IfCleaned bit default(0) not null
对Mailing list表执行
alter table t_MailingList add IfCleanning bit default(0) not null
简简单单的两个语句,在执行过程中,Solution生产环境机器变得无法访问,远程连不上,Solution程序也连不上了。后来不得不打电话到萧山机房叫机房那边把机器强制重启。
当时就分析原因应该是整个脚本需要执行的t_User表太多,表中数据太大,引起数据库将内存或者磁盘资源占满了。t_User表中有几千万数据的表也存在的。
以后对大数据量的表进行操作时要格外小心,不管是程序对表的操作,还是数据库升级时对表的操作,都需要在大数据量下进行完备的测试后才可以进行发布。
经过讨论和研究,新的脚本如下,将原先一步的脚本分为好多步,而且,在第三步中又分为好多步。方法主要参考右侧的StackOverFlow的文章。http://stackoverflow.com/questions/287954/how-do-you-add-a-not-null-column-to-a-large-table-in-sql-server
第一步,增加新列,赋予默认值,允许为NULL
alter table t_User***** add NewColumnIfCleaned bit default(0)
这样,表中原有记录的值均为NULL,
但若有新的记录插入进来,新纪录的该列值为默认的0.
第二步,增加一个NOT NULL的约束,并设置NOCHECK
alter table t_User***** with nocheck add constraint NewColumnIfCleaned_NotNull check (NewColumnIfCleaned is not null)
这样,表中原有记录仍可保持为NULL,
若插入新纪录,则会有这个NOT NULL的约束
第三步,分批将原有记录更新为0. 一次执行3000条,完整的脚本如下。
原文章中的Go 1000的方法在我们这里并不适用,因为我们要GO多少次是不确定的,要根据t_user表数据量来计算出来的。
declare @i int, @strSql nvarchar(2000), @table nvarchar(200), @start int, @strNum nvarchar(100), @preUpate int, @totalCount int, @goCount int, @siteDelay datetime, @dbDelay datetime, @tbDelay datetime;
select @preUpate=3000, @siteDelay='00:00:02', @dbDelay='00:05:00', @tbDelay='00:00:01';
declare @time1 datetime;
select @time1=GETDATE();
--更新Site****库
use [Comm100.Site****]
select @totalCount=0,@goCount=0,@i=0,@start=10000000;
while @i<500
begin
select @strNum= CONVERT(nvarchar(50),@start+@i);
select @table='t_User'+@strNum;
select @strSql='if exists (select top 1 * from [dbo].[sysobjects] where [Id]=object_id(N''[dbo].['+@table+']'') and objectproperty(id, N''IsUserTable'') = 1)
begin
if exists(select * from syscolumns where id=OBJECT_ID('''+@table+''') and name=''IfCleaned'')
begin
select @totalCount1=count(0) from '+@table+' where IfCleaned is null;
end
end
';
--print @strSql;
exec sp_executesql @strSql,N'@totalCount1 int output',@totalCount output;
if(@totalCount>0)
begin
select @goCount=@totalCount / @preUpate +1;
while (@goCount>0)
begin
select @strSql='
update top('+CONVERT(nvarchar(10),@preUpate)+') '+@table+' set IfCleaned=0 where IfCleaned is null;
';
--print @strSql;
exec(@strSql);
select @goCount=@goCount-1;
waitfor delay @tbDelay;
end
end
set @i=@i+1;
waitfor delay @siteDelay;
end
select DATEDIFF(MILLISECOND,@time1,GETDATE());
注:在新的SQL Server 2012中,在表中增加一个NOT NULL的字段,情况好像有所不同,
Adding NOT NULL Columns as an Online Operation
In SQL Server 2012 Enterprise Edition, adding a NOT NULL column with a default value is an online operation when the default value is a runtime constant. This means that the operation is completed almost instantaneously regardless of the number of rows in the table. This is because the existing rows in the table are not updated during the operation; instead, the default value is stored only in the metadata of the table and the value is looked up as needed in queries that access these rows. This behavior is automatic; no additional syntax is required to implement the online operation beyond the ADD COLUMN syntax. A runtime constant is an expression that produces the same value at runtime for each row in the table regardless of its determinism. For example, the constant expression "My temporary data", or the system function GETUTCDATETIME() are runtime constants. In contrast, the functions NEWID() or NEWSEQUENTIALID() are not runtime constants because a unique value is produced for each row in the table. Adding a NOT NULL column with a default value that is not a runtime constant is always performed offline and an exclusive (SCH-M) lock is acquired for the duration of the operation.
While the existing rows reference the value stored in metadata, the default value is stored on the row for any new rows that are inserted and do not specify another value for the column. The default value stored in metadata is moved to an existing row when the row is updated (even if the actual column is not specified in the UPDATE statement), or if the table or clustered index is rebuilt.
Columns of type varchar(max), nvarchar(max), varbinary(max), xml, text, ntext, image, hierarchyid, geometry, geography, or CLR UDTS, cannot be added in an online operation. A column cannot be added online if doing so causes the maximum possible row size to exceed the 8,060 byte limit. The column is added as an offline operation in this case.
大数据量表中,增加一个NOT NULL的新列的更多相关文章
- (转)SqlServer为大数据量表建索引
本文转载自:http://blog.csdn.net/iangujun/article/details/8136764 之前从没有用SqlServer数据库处理过大数据量的表,都是用Oracle,然后 ...
- [moka同学笔记]Yii2.0给一张表中增加一个属性
1.model中建立关联 public function getUser(){ return$this->hasOne(User::className(),['id'=>'uid']) ; ...
- 向数据库中全部表中增加一个字段的SQL
SELECT 'ALTER TABLE ' + NAME + ' ADD 字段名 int not null default 0' FROM sysobjects AS sWHERE s.[type] ...
- java大数据量调优
从总体上来看,对于大型网站,比如门户网站,在面对大量用户访问.高并发请求方面,基本的解决方案集中在这样几个环节:1.首先需要解决网络带宽和Web请求的高并发,需要合理的加大服务器和带宽的投入,并且需要 ...
- 在数据表中添加一个字段的SQL语句怎么写
如果要在数据表中添加一个字段,应该如何表示呢?下面就为您介绍表添加字段的SQL语句的写法,希望可以让您对SQL语句有更深的认识. 通用式: alter table [表名] add [字段名] 字 ...
- 解决WCF大数据量传输 ,System.Net.Sockets.SocketException: 远程主机强迫关闭了一个现有的连接
开发中所用的数据需要通过WCF进行数据传输,结果就遇到了WCF大量传输问题 也就是提示System.Net.Sockets.SocketException: 远程主机强迫关闭了一个现有的连接 网上解决 ...
- asp.net中绘制大数据量的可交互的图表
在一个asp.net项目中要用到能绘制大数据量信息的图表,并且是可交互的(放大.缩小.导出.打印.实时数据),能够绘制多种图形. 为此进行了多方调查预研工作,预研过微软的MsChart图表组件.基于j ...
- c#中@标志的作用 C#通过序列化实现深表复制 细说并发编程-TPL 大数据量下DataTable To List效率对比 【转载】C#工具类:实现文件操作File的工具类 异步多线程 Async .net 多线程 Thread ThreadPool Task .Net 反射学习
c#中@标志的作用 参考微软官方文档-特殊字符@,地址 https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/toke ...
- MySQL大数据量快速分页实现(转载)
在mysql中如果是小数据量分页我们直接使用limit x,y即可,但是如果千万数据使用这样你无法正常使用分页功能了,那么大数据量要如何构造sql查询分页呢? 般刚开始学SQL语句的时候,会这 ...
随机推荐
- runtime error (运行时错误)
比如说: ①除以零 ②数组越界:int a[3]; a[10000000]=10; ③指针越界:int * p; p=(int *)malloc(5 * sizeof(int)); *(p+10000 ...
- 基于VUE2.0的分页插件(很好用,很简单)
基于jQuery的分页插件很多,今天分享一下基于Vue的分页插件pagination.js,该插件使用用感觉很不错,简单不复杂,现将个人使用过程中的方法与遇到的问题以及实例分享出来. 下载解压的主要目 ...
- QLabel 内容长度超过控件本身长度时超出的部分用省略号
void JunEditableLabel::setText(const QString &string) { QFont font("Tahoma"); font.set ...
- Eclipse之NDK编译-- Type 'jint' could not be resolved, and JNIEnv, jclass错误解决办法
最近在研究面部识别美白相关的功能.使用的是opencv,就去研究了.今天正好有空就把安装了ndk,安装完成之后就试图去编译demo程序,hellow-jni c代码,一开始编辑就报错了3个错误信息: ...
- opencv实现遍历文件夹下所有文件
前言 最近需要将视频数据集中的每个视频进行分割,分割成等长的视频片段,前提是需要首先遍历数据集文件夹中的所有视频. 实现 1.了解opencv中的Directory类: 2.实现测试代码: 系统环境 ...
- 转:如何解决VC "应用程序无法启动,因为应用程序的并行配置不正确 sxstrace.exe"问题
如何解决VC "应用程序无法启动,因为应用程序的并行配置不正确 sxstrace.exe"问题 引用链接 http://blog.csdn.net/pizi0475/artic ...
- dfs遍历痕迹的清理
dfs 根据遍历效果分为 有痕迹遍历和无痕迹遍历, 有痕迹遍历就是对遍历过程对全局变量进行了修改的遍历(如POJ3009中的冰球问题,每次遍历会对地图造成影响),无痕迹遍历就是不对全局变量修改的遍历( ...
- bool dfs 解决单一解问题的优越性
dfs的返回值类型可以是int 或者 void .bool 由void 与 int 作为返回值类型的dfs在得到解之后不能立即返回,即使你加上语句if(key)return;也要在得到解之后一点点返 ...
- 《DSP using MATLAB》Problem 4.13
代码: %% ---------------------------------------------------------------------------- %% Output Info a ...
- hdu1227 dp
题意:在一条路上有 n 个站点,并给定了每个站点的坐标,然后想要在 k 个站点旁边分别各建一个补给站,求所有站点到最近的补给站的距离和的最小值. 是的,毫无疑问,显然是 DP 问题,但是这题怎么递推还 ...