2011-04-22 72 views
3

我运行了一个查询来从一个表复制1800万条记录到另一个表。由于查询需要很长时间才能运行,因此我正在监视表计数以确定何时完成。取消插入查询 - 花费时间

我注意到它达到它应该达到的次数开始下降回落,所以我检查了日志,它看起来像SQL服务器基本上耗尽了内存在号码前:

“的SQL Server数据库的实例引擎目前无法获取LOCK资源。在活动用户较少时重新运行您的声明。请数据库管理员检查此实例的锁定和内存配置,或检查长时间运行的事务。

实际插入只跑了约20分钟前,错误日志中出现了。 大约2小时前我从管理工作室取消了查询,并根据桌子数量判断,这件事情只完成了25%,这使我的时间增加了大约6个小时。我假设了一些事情,因为所有的内存都用完了,现在它正在运行页面文件,这就是为什么它需要这么长时间。

有什么我可以做,以加快这?它基本上使数据库无法使用,因为每个人都得到'无法获取锁资源'的错误。我可以很容易地自己删除插入的记录,如果也许我可以杀死进程ID并且自动插入“回滚”,我就会流浪。

更新

这件事是直到运行显着变慢。我发现的一件事是,由以下查询给出的#锁似乎很离谱:83百万。次高的是高达20。

SELECT request_session_id, COUNT (*) num_locks 
FROM sys.dm_tran_locks 
GROUP BY request_session_id 
ORDER BY count (*) DESC 
+0

嗯,我想它将无法释放锁定,直到事务完成回滚,并且它不会获得可能触发锁定升级尝试的新锁定,因此无法想到可以释放该内存。我不认为你可以杀死一个回滚事务,如果你尝试重新启动,我认为它会在数据库恢复期间重新获得所有原始锁定,所以这也不会帮助你... – 2011-04-22 15:31:48

+0

RE:你的编辑96字节每个lock * 83,000,000给出7,968,000,000,所以你单独为这些锁使用'7.42 GB'的内存。该实例上有多少内存可用于SQL Server?你也使用默认设置,或者你是否改变了'locks'配置选项和/或设置任何与锁相关的跟踪标志。 – 2011-04-22 18:29:03

+0

服务器上的32 Gig的ram,我不知道它有多少分配给SQL Server,可能无论默认设置是什么。锁配置也是如此,可能是默认设置。 – 2011-04-22 18:31:50

回答

0

解决方案适用于我的是重新启动服务器。对于我正在用来恢复的数据库,确实花费了12个小时 - 但重新启动后,我们清除了应用程序访问其他数据库时遇到的资源问题。下一次我尝试这个时候,我把它分解成了500K的批次,而不是所有的1800万,一切正常。

-1

断开所有其他用户进程。您甚至可能必须将数据库更改为“仅限管理员”以防止其他连接。确保您没有其他正在运行的阻止原始更新语句的处理。

希望这将释放一些内存和/或防止其他进程使用的是什么小内存可用。

此命令将刷新出高速缓存,可通过从内存中删除所有缓存数据可能的帮助。希望这会删除其他进程使用的数据,并为当前查询腾出更多空间。

DBCC DROPCLEANBUFFERS

+0

DBCC DROPCLEANBUFFERS不会更改回滚需要的时间量。 – 2011-04-26 21:18:51

+0

我从来没有说过会。我只是希望为目前的主流程使用释放尽可能多的内存。 – datagod 2011-04-27 14:06:58

0

一旦你得到的东西取消了,你需要修复你的代码做插入。首先,如果您一次在游标中运行一条记录(并且所有记录都在同一个事务中),那么这些记录将永远运行。如果您使用基于集合的插入,则可能会遇到您描述的问题。如果您可以使用可以很好地工作的批量插入来执行此操作,或者您所做的操作是逐行和基于集合的方法的组合,即在循环中运行批处理记录。 (我通常每次从2000开始,如果这是快速移动到更多的记录。)只要确保测试,你不是试图重复插入同一批记录。

+0

谢谢,我喜欢并一直使用散装插页,在这个场景中,这是不可能的 – 2011-04-22 17:41:23

0

我不认为重新启动是必需的。重新启动SQL Server Service就足够了。我会建议重新启动SQL server service。它会解决问题。