我想将SQL-Server数据库中表的某些列(不是全部)的所有值设置为 NULL。问题是,该表有超过 30.000.000 行,更新所有列/行需要很长时间。如何加快以下更新语句?
Update Table
Set
column1 = null,
column4 = null,
column8 = null,
column12 = null
不能掉表!
我想将SQL-Server数据库中表的某些列(不是全部)的所有值设置为 NULL。问题是,该表有超过 30.000.000 行,更新所有列/行需要很长时间。如何加快以下更新语句?
Update Table
Set
column1 = null,
column4 = null,
column8 = null,
column12 = null
不能掉表!
问题是,该表有超过 30.000.000 行,更新所有列/行需要很长时间。如何加快以下更新语句?
您购买了更快的服务器。
严重地。
无法删除表。必须在一个语句中更新 3000 万行。
这是不可改变的两面。不可能进行很多优化(您可以杀死该字段上的任何索引,然后重新创建它们)。剩下的是越来越好的硬件。
抱歉,没有更好的答案。您可以尝试在循环中一次更新 10000 次 - 这会使事务和语句更快,但我怀疑它会使整个操作更快,这是您的问题所在。最后必须完成工作,如果需要更快地完成,那么您需要更多的功率 = 更快的服务器。
如果列在表的末尾,或者列的顺序不相关,我认为最快的方法是删除列并重新创建它们
-- assumes no constraints defined on the columns
alter table MyTable
drop column Column1, Column2, ...
alter table MyTable
add column Column1 int null, Column2 varchar(max) null, ...
Additionally if the updates are slow in general, it might be a case of over-indexing. Take a look at the indexes that are defined on the table, how many of them there are, what columns are they referencing, etc. In general, inserts and updates get slower with any index defined. However, selects can get much faster, so do not just go in and ax all indexes, but try to locate any indexes that are seldom or never used.
And last, if the database is properly indexed and still too slow, take a look at TomTom's answer.
Edit:
To address the comment about column ordering in SQL Server tables, in most cases it's totally unimportant, however there are few scenarios where it must be maintained:
ModifiedBy
and ModifiedOn
columns are not the last two columns in the tableAnother approach that could help is to disable all indexes used on those fields before running the update, and then rebuilding them afterwards. This will eliminate some of the I/O overhead.
A second option is to select all of the data from your table into a new table, with the nulls replacing the columns as needed. Then, truncate the first table, enable identity insert, and select everything from the new table back into the first one. This would also benefit from the disabling of indexes.
An UPDATE without WHERE tries to update all rows, even those that already have a NULL in the columns. A seemingly pointless filter like the one belong can have a BIG impact.
UPDATE Table
SET
column1 = null,
column4 = null,
column8 = null,
column12 = null
WHERE
column1 IS NOT NULL OR
column4 IS NOT NULL OR
column8 IS NOT NULL OR
column12
Or, probably better, depending on distribution:
UPDATE Table SET column1 = NULL WHERE column1 IS NOT NULL
UPDATE Table SET column2 = NULL WHERE column2 IS NOT NULL
UPDATE Table SET column4 = NULL WHERE column4 IS NOT NULL
UPDATE Table SET column8 = NULL WHERE column8 IS NOT NULL
UPDATE Table SET column12 = NULL WHERE column12 IS NOT NULL
If it still takes way too long time, try using top (10000) on either solution and repeat until done.
UPDATE top (10000) Table SET column1 = NULL WHERE column1 IS NOT NULL
etc...