MSSQL Batch INSERT操作会增加内存使用量

时间:2014-03-07 21:42:44

标签: sql sql-server memory ram

我在MSSQL 2012上运行了以下批量插入查询:

WHILE 1<2 --busy loop until user stops the query
BEGIN

DECLARE @batch int = 200000

BEGIN TRANSACTION

WHILE @batch > 0
BEGIN

DECLARE @hourRand int = CONVERT(int,60*RAND() )
DECLARE @minRand int = CONVERT(int,60*RAND() )
--...more DECLAREs... --

INSERT INTO dbo.details (COLUMN1,COLUMN2) VALUES (@hourRand, @minRand, ...)

set @batch = @batch - 1
END

COMMIT

END

当我离开此查询时,SQL的内存使用量不断增长。为什么这个循环会导致内存增长?插入的条目是否存储在占用内存的某种缓存或缓冲区中?如果是这样,我如何释放正在使用的内存?

我知道SQL会根据需要增加内存池,但是当服务器的内存使用率接近98%时,我的查询会开始挂起,所以我不认为它只是内存池很大。 SQL似乎实际上是“使用”它所持有的大部分内存。

重新启动服务器会按预期释放内存,但我不能让服务器经常耗尽内存。

感谢您的帮助!

3 个答案:

答案 0 :(得分:2)

这里没有问题。所有服务器数据库都广泛使用缓存,除非需要,否则不释放内存,例如因为可用的空闲RAM低于某个阈值。服务器不会耗尽RAM。尝试“释放”内存会降低性能,因为服务器必须从存储中读取数据。

至于处理查询,它可能更多地与您在单个事务中发出200K insert语句并且您可能遇到锁定或死锁问题这一事实有关。

这是一个人工示例,不显示批处理操作中服务器的行为。批次永远不会超过200K。如果要导入200K行,请在服务器端使用BULK INSERT或在客户端使用SqlBulkCopy。

SQL Server用于数据仓库应用程序,其中典型的导入大小为数百万行。诀窍是使用适当的工具来完成这项工作,例如BULK INSERT,SSIS和正确使用登台数据库。

答案 1 :(得分:1)

因为你在TRANS中做了所有这些工作。

COMMITINSERT或更好,但删除您的BEGIN TRANSACTION和COMMIT

答案 2 :(得分:0)

您正尝试插入200000条记录。

您最初尝试在每条记录中提交,插入速度非常慢。然后在所有插入结束后更改了提交。

尝试使用计数器来插入记录数 在此计数器达到10000并将其重新初始化为0时提交。

不要忘记最后有一个提交 这应该可以解决您的内存问题,插入也应该更快。继续使用数字10000,直到您对插入速度和内存使用情况感到满意为止。