在运行大批插入时,有什么方法可以解决内存不足问题?

时间:2012-02-10 19:08:41

标签: sql-server-2008

我正在尝试运行一大批插入语句(大约30兆),以重新同步一个数据库以匹配另一个数据库。我在Win 7机器上运行SQL Server 2008 R2 64位,内存为8 GB。

当我在SSMS中运行查询时,我得到“查询执行错误”而没有输出消息。经过一些摆弄并尝试在SSMS之外运行它之后,我意识到这是一个内存不足的错误。事实上,即使它出错了,我发现SQL Server服务正在使用大约5.5 GB的内存!

我可以调整一个参数,允许SQL运行吗?另一种方法是编写一个程序,将查询分解为批处理并运行它们。有趣的是,这似乎只发生在包含插入的大型查询中。包含更新的大型查询似乎工作正常。也许这是由于它们写入事务日志的方式。但是,查询将作为一系列插入输出,并且无法更改。

无论如何,SQL Server中是否有设置可以调整以解决此问题?我很感激任何人都可以提出任何建议。

编辑:感谢您的回复,蓝脚。当我们第一次看到无信息错误时,我的同事和我有同样的印象 - 看起来SSMS内存不足。但是,在进一步检查时,它看起来可能是SQL Server。让我解释。我们正在使用Red Gate的SQL Comparison SDK与Visual Studio生成差异查询,然后有条件地运行某些语句,以便根据某些规则使2个数据库收敛。因此,在遇到此问题后,我们使用包含的Executor对象来运行脚本。我们收到了以下错误:

System.Data.SqlClient.SqlException occurred
  Message=There is insufficient system memory in resource pool 'internal' to run this query.
  Source=.Net SqlClient Data Provider
  ErrorCode=-2146232060
  Class=17
  LineNumber=79180
  Number=701
  Procedure=""
  Server=QA1
  State=123
  StackTrace:
       at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
       at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
       at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
       at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
       at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async)
       at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
       at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
       at RedGate.Shared.SQL.ExecutionBlock.BlockExecutor.ExecuteBlock(ExecutionBlock block, String server, String database, Boolean integratedSecurity, String userName, String password)
       at IO.Practiceware.DbSync.Csharp.Program.RunScript(String path, String server, String database)
  InnerException: 

我不知道可以做些什么,但是我知识渊博的同事说这基本上意味着SQL Server本身内存不足。我很感激你对此有任何见解。

1 个答案:

答案 0 :(得分:2)

一些想法:

尝试将插入分批分批。每1000行左右插入如下内容:

INSERT ...
INSERT ...
INSERT ...

GO

INSERT ...
INSERT ...
INSERT ...

偶尔发布CHECKPOINT以减少对日志的影响也可能不会受到伤害。

尝试将它们组合起来,而不是发送数千个单独的插入语句。您可以通过多种方式执行此操作,例如:

INSERT dbo.table(col1,col2) SELECT 1,2
UNION ALL SELECT 2,2
UNION ALL SELECT 3,2;

-- or    

INSERT dbo.table(col1,col2)
VALUES(1,2),(2,2),(3,2);

此外,您可以将数据(而不是插入命令)存储在平面文本文件中,并使用BULK INSERTbcp等代替常规插入。