2010-05-18 321 views
3

在复制大量数据并将其插入同一个表的插入语句中使用ROWLOCK是明智的做法吗?在INSERT语句中使用ROWLOCK(SQL Server)

例)

INSERT INTO TABLE with (rowlock) (id, name) 
    SELECT newid, name 
    FROM TABLE with (nolock) 
    WHERE id = 1 

有谁知道,关于如何提高这种说法的建议,因为我看到当SQL Server变得繁忙它最终在超时查询返回的SQL Server。

+0

是插入到新表中的表,还是现有数据在表中的表? – AdaTheDev 2010-05-18 12:57:24

+0

你能解释你为什么这样做吗?另外,你为什么使用(nolock)提示? – datagod 2016-01-05 18:29:24

回答

1

你可能最好将子查询结果存储在临时表中并插入。

+0

为什么会这样?这将有效地增加插入量。 – usr 2012-10-20 16:51:17

0

如果您插入大量数据,并且读写器出现问题(锁定,超时),您应该将插件分成几部分(排名前100位),直到完成所有数据。如果你不这样做,即使你声明了rowlock,锁定升级可能会发生,在这种情况下,SQL Server将在你插入数据时获得一个表锁。

另一个不错的选择是使用SNAPSHOT隔离,如果您有足够的可用空间,这将是完美的。 对于第一种选择读hereQ

http://support.microsoft.com/kb/323630

0

如果您要插入大量的数据,例如1000行以上,那么你可以考虑使用临时表或表变量。首先将行插入临时表或变量,然后执行insert into final_table select * from temp table将工作得很好。如果您需要更多的行,那么只需将插入内容放在游标中,并迭代每1000行,直到完成总行数。

对于更复杂的插入操作,如果您需要保留身份钥匙,或者将它们用作其他表格中的参考钥匙,则可以将整个存储过程放入事务中,并计算最后使用的身份钥匙表,并将其用作临时表的身份密钥的第一个值,或者将设置标识关闭

0

那么,不可能在INSERT语句中使用WITH(NOLOCK)表提示。请参阅https://docs.microsoft.com/en-us/sql/t-sql/statements/insert-transact-sql#arguments

如果在任何给定时间只有一个进程或应用程序在同一个表内复制数据,那么各种事务隔离级别对您而言并不会有多大帮助。它们旨在隔离(分开)不同的交易,并且对单一交易没有影响。

此外,通常最好将查询优化委托给SQL Server,因为查询的所有必要元素都是已知的,并且存在 - 我假设 - 没有针对同一个表的其他竞争查询,这可能会导致混乱优化的查询执行计划。