我正在尝试运行一大批插入语句(大约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本身内存不足。我很感激你对此有任何见解。
答案 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 INSERT
,bcp
等代替常规插入。