SQL Server在查询执行后未释放内存

33

我认为我有一个基本问题,可能许多人都遇到过。当我在 SQL Server 中运行查询时,它会将所有需要进行查询执行的数据加载到内存中(例如,如果存在联接,则会从这两个表中加载必要的数据),但当查询执行完成后,SQL Server 消耗的内存并没有释放。

我之前注意到了这一点,因为我正在分析一个占用大量临时空间的查询。当我运行查询时,它最终会消耗多达 25 GB 的 RAM。这 25 GB 的 RAM 除非我重启 MSSQLSERVER 服务,否则不会被释放。

您们如何管理 SQL Server 内存?这显然是一个问题,对吧?

我也想听听您是否有针对单个查询清除已使用内存的特定方法。

提前感谢!


2
你使用的是哪个版本?这是一个已知的问题,适用于SQL Server 2008 R2及以下版本。我不确定2012是否存在该问题。我会很快提供答案... - MoonKnight
6
“这显然是一个问题,对吧?” - 不是。而且像Killercam说的那样,这也不是一个“问题”。SQL Server被设计来获取并保留内存,除非操作系统发出信号表示它的运行空间不足。从长远来看,哪种方式更好呢?SQL Server处理每个查询,承担任何/所有将数据加载到内存中的I/O成本,但然后整洁地将所有数据全部清除,或者它让数据一直挂在那里,以防未来的查询可以从已经加载的数据中受益? - Damien_The_Unbeliever
3
同意。但在许多情况下,我可以确定查询不会再被使用。我希望在这种情况下释放内存。感谢您的回复。 - Kumar Vaibhav
4
重点是,这就是服务器的设计。当它需要更多内存时,它会从操作系统中获取,但随后开始管理该内存,决定放入什么等等。除非操作系统发出低内存信号,否则它不会归还内存。 - Damien_The_Unbeliever
2
绝对同意。但是如果我确实想要以编程方式释放内存,该怎么办? - Kumar Vaibhav
显示剩余10条评论
4个回答

30

SQL Server被设计为尽可能地请求更多的RAM,除非操作系统明确需要这些内存。我认为最好的方法是限制服务器可以使用的RAM数量,这将允许操作系统有一定量的资源可供使用。要设置此选项,请参阅使用SQL Server Management Studio配置内存选项:

使用两个服务器内存选项min server memory(最小服务器内存)max server memory(最大服务器内存)重新配置SQL Server Memory Manager所管理的内存量(以兆字节为单位),用于SQL Server实例。

  1. 在“对象资源管理器”中,右键单击服务器并选择属性
  2. 单击内存节点。
  3. 服务器内存选项下,输入您想要的最小服务器内存最大服务器内存的数量。

您也可以使用以下T-SQL命令(示例)进行设置:

exec sp_configure 'max server memory', 1024
reconfigure

限制内存使用量为1GB。

注意:上述设置并不会将SQL Server的所有方面都限制在该内存量上,它仅控制缓冲池和执行计划缓存。CLR、全文检索、SQL Server .exe文件实际使用的内存、SQL Agent、扩展存储过程等其他事物不能通过此设置进行控制。然而这些其他事物通常不需要太多的内存,主要是缓冲池和执行计划缓存需要大量内存。

希望能对您有所帮助。


那么,没有释放查询所使用的内存的选项,对吧? - Kumar Vaibhav
1
不行。你必须重新启动服务才能强制释放。限制消耗的唯一方法就是如上所述。我还没有开始使用2012,这可能已经得到解决(尽管我怀疑,因为SQL Server主要用于基于服务器的事务处理,正如上面的讨论所确定的那样-在这里,这种行为不是问题)。如果您正在从应用程序运行SQL服务,也许您可以通过暂时使用操作系统资源来强制释放内存-但是,我不建议这样做,也没有尝试过... - MoonKnight
2
我遇到了类似的问题...然而,一旦SQL服务器内存使用率达到峰值,新的查询就会出现超时错误,除了重新启动MSSQL服务器外,没有其他方法。这里可能出了什么问题?如何解决? - Krunal
@Krunal - 你能解决它吗? - Kumar Vaibhav

6
我也遇到了上面提到的同样问题。 但是运行以下查询可以释放 RAM 内存,但在不到 5 小时内,RAM 内存就被占用了。因此我又必须强制释放 RAM 内存。
EXEC sys.sp_configure N’show advanced options’, N’1' RECONFIGURE WITH OVERRIDE
GO
EXEC sys.sp_configure N’max server memory (MB)’, N’2048'
GO
RECONFIGURE WITH OVERRIDE
GO
EXEC sys.sp_configure N’show advanced options’, N’0' RECONFIGURE WITH OVERRIDE
GO

然后运行以下命令:
2.
EXEC sys.sp_configure N’show advanced options’, N’1' RECONFIGURE WITH OVERRIDE
GO
EXEC sys.sp_configure N’max server memory (MB)’, N’6144'
GO
RECONFIGURE WITH OVERRIDE
GO
EXEC sys.sp_configure N’show advanced options’, N’0' RECONFIGURE WITH OVERRIDE
GO

4

我认为没有强制SQL Server释放内存的方法。 不过,你可以限制内存使用。

sp_configure 'max server memory', <memory_size MB>
reconfigure

MSDN


1

虽然这是一个老问题,但我想补充我的意见。主要是基于上面的回答,使用dsql自动将内存量缩小到先前的值后回滚。虽然有点丑陋,但它确实有效。

IF OBJECT_ID(N'tempdb..##globaltemp') IS NOT NULL
BEGIN
    DROP TABLE ##globaltemp
END

SELECT TOP 1 value
INTO ##globaltemp
FROM sys.configurations
WHERE NAME LIKE '%server memory%'
ORDER BY NAME
OPTION (RECOMPILE);

EXEC sys.sp_configure N'max server memory (MB)'
    , N'1024'
GO

RECONFIGURE
WITH OVERRIDE
GO

DECLARE @dsql AS VARCHAR(20)

SELECT @dsql = cast(value AS NVARCHAR(20))
FROM ##globaltemp

EXEC sys.sp_configure N'max server memory (MB)'
    , @dsql
GO

RECONFIGURE
WITH OVERRIDE
GO

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接