这是做什么的?

时间:2011-04-08 20:40:43

标签: sql tsql

有一段时间,我需要清除数据库中的匿名用户配置文件。一位同事建议我使用这个程序,因为它可以不时地为其他程序运行一点喘息空间。

WHILE EXISTS (SELECT * FROM aspnet_users WITH (NOLOCK)  
    WHERE userID IN (SELECT UserID FROM #AspnetUsersToDelete))
BEGIN
  SET ROWCOUNT 1000
  DELETE FROM aspnet_users WHERE userID IN (SELECT UserID FROM #AspnetUsersToDelete )
  print 'aspnet_Users deleted: ' + CONVERT(varchar(255), @@ROWCOUNT) 
  SET ROWCOUNT 0
  WAITFOR DELAY '00:00:01'
END

这是我第一次看到使用的NOLOCK关键字,而rowcount的逻辑似乎是向后退的。是否有其他人使用类似的技术在长时间运行的过程中提供窗口,这是最好的做事方式吗?

3 个答案:

答案 0 :(得分:6)

任何时候我预计会删除大量的行,我会做类似的事情来保持交易批量大小合理。

对于SQL Server 2005+,您可以使用DELETE TOP (1000)...代替SET ROWCOUNT语句。我通常会这样做:

SELECT NULL; /* Fudge @@ROWCOUNT value for first time in loop */

WHILE (@@ROWCOUNT <> 0) BEGIN
    DELETE TOP (1000)
    ...
END /* WHILE */

答案 1 :(得分:2)

SET ROWCOUNT 1000表示它只会处理以下语句中的一千行(即DELETE语句)。 SET ROWCOUNT 0表示每个语句处理但是许多行都是相关的。

所以基本上,它会删除一千行,等待一秒,删除另一千行,然后继续删除,直到没有更多要删除。

WITH (NOLOCK)可防止数据被锁定,这意味着同时运行的多个查询可以访问数据。这使您的查询更快一些。有关NOLOCK的更多信息,请参阅以下链接:

http://www.mollerus.net/tom/blog/2008/03/using_mssqls_nolock_for_faster_queries.html

答案 2 :(得分:2)

(NOLOCK)允许脏读。基本上,如果您在更新过程中从表中读取数据,则可能会读取错误的数据。您还可以读取尚未提交的事务已修改的数据以及一系列其他问题。

最佳做法是不使用NOLOCK,除非您从真正不更改的表(例如包含状态的表)或从未经常更新的数据仓库类型DB中读取。