Large scale data, add new columns of a NOT NULL

 

This time, publish a list of cleaning function, the database needs to be upgraded. MailingList table add IfCleaning field, all t_User * Table add IfCleaned field.

 

Script as follows

All t_User execution table

alter table t_User** add IfCleaned bit default(0) not null

For Mailing list execution table

alter table t_MailingList add IfCleanning bit default(0) not null

 

Simple two statements, in the implementation process, Solution production machine becomes inaccessible, remote Rom, Solution program also Rom. And later I had to call to Xiaoshan room called the machine room over there to force a restart.

 

At that time, analyze the reasons should be the entire script to be executed t_User table too much, too much data in the table, the database will lead to memory or disk resources already occupied. t_User table has tens of millions of data tables also present.

 

Be careful when after large amounts of data tables to operate, regardless of program operations on the table, or database upgrade operations on the table, need to be fully tested in a large amount of data before they can be released.

 

After discussion and research, new script follows the original script into a lot of step-by-step, and, in the third step is divided into a lot of steps. The main method reference to the right of StackOverFlow article. http://stackoverflow.com/questions/287954/how-do-you-add-a-not-null-column-to-a-large-table-in-sql-server

 

The first step, adding new columns, given default, allowing for the NULL

alter table t_User***** add NewColumnIfCleaned bit default(0)

In this way, the value of the original record of the table are NULL ,

But if a new record is inserted in, this column is the default new record of 0.

 

The second step, add a NOT NULL constraint, and set NOCHECK

alter table t_User***** with nocheck add constraint NewColumnIfCleaned_NotNull check (NewColumnIfCleaned is not null)

Thus, the table can remain the original record is NULL ,

If you insert a new record, then there will be the NOT NULL constraints

 

The third step, the original batch record is updated to 0. first performance 3000 Tiao , complete the following script.

Original article Go 1000 method is not applicable in our case, because we want to GO How many times are uncertain, according to t_user be calculated from the amount of table data.

 

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();

 

- Update Site **** library

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());

 

Note: In the new SQL Server 2012 , the increase in a table NOT NULL fields, the situation seems to be different,

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.

Reproduced in: https: //www.cnblogs.com/henryhappier/p/3214439.html

Guess you like

Origin blog.csdn.net/weixin_34191845/article/details/93537294