【问题标题】:SQL Server not releasing memory after query executes查询执行后 SQL Server 不释放内存
【发布时间】:2013-06-21 21:05:48
【问题描述】:

我想我有一个很多人可能遇到过的基本问题。当我在 SQL Server 中运行查询时,它将在内存中加载执行查询所需的所有数据(例如,如果存在连接,则它将从这两个表中加载必要的数据),但是当查询完成执行内存时SQL Server 使用的未释放。

我注意到这一点是因为几天前我正在分析一个占用大量 tempdb 空间的查询。当我过去运行查询时,它会(在执行结束时)消耗多达 25 GB 的 RAM。除非我重新启动 MSSQLSERVER 服务,否则不会释放这 25 GB RAM。

你们是如何进行 SQL Server 内存管理的?这显然是个问题吧?

我也想知道你是否做了一些特定的事情来清除单个查询所用的内存。

提前致谢!

【问题讨论】:

  • 你用的是什么版本?这是 SQL Server 2008 R2 之前的已知问题。我不确定 2012 年。我会尽快提供答案...
  • "这显然是个问题吧?" - 不。这不是 Killercam 所说的“问题”。 SQL Server 设计是为了抢占内存并保持它,除非操作系统发出它运行不足的信号。从长远来看,哪个更好 - SQL Server 处理每个查询,产生将数据加载到内存中的任何/所有 I/O 成本,但随后巧妙地将所有这些数据再次抛出,或者它一直在徘徊以防将来的查询将从已经加载的数据中受益?
  • 同意。但在许多情况下,我确定不会再次使用该查询。我希望在这种情况下释放内存。感谢您的回复。
  • 重点是,这就是服务器设计要做的事情。当它需要更多内存时,它会从操作系统中获取内存,然后 开始管理该内存,决定在其中放入什么等。除非操作系统发出低内存信号,否则它不会归还内存。
  • 绝对同意。但是,如果我确实想以编程方式释放内存该怎么办?

标签: sql sql-server-2008 memory-management


【解决方案1】:

SQL Server 确实旨在请求尽可能多的 RAM,除非操作系统明确需要此内存,否则这些 RAM 不会被释放。我认为最好的方法是限制服务器可以使用的 RAM 数量,这将允许操作系统拥有一定数量的资源来使用任何东西。设置这个How to configure memory options using SQL Server Management Studio

使用两个服务器内存选项,min server memoryma​​x server memory,重新配置 SQL Server 内存管理器管理的内存量(以 MB 为单位) SQL Server 的一个实例。

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

您也可以使用以下命令(示例)在 T-SQL 中执行此操作:

exec sp_configure 'max server memory', 1024
reconfigure

将消耗限制为 1GB。

注意:以上内容不会将 SQL Server 的所有方面都限制为该内存量。这只控制缓冲池和执行计划缓存。 CLR、全文、SQL Server .exe 文件、SQL 代理、扩展存储过程等使用的实际内存不受此设置控制。然而,这些其他东西通常不需要那么多内存,它是缓冲池和执行计划缓存需要大量内存。

我希望这会有所帮助。

【讨论】:

  • 所以没有选项可以释放查询使用的内存对吧?
  • 没有。您必须重新启动服务才能强制发布。限制消费的唯一方法是如上。我还没有开始使用 2012,这可能已经解决(尽管我对此表示怀疑,因为 SQL Server 主要用于基于服务器的事务,并且正如上面的讨论正确建立的那样 - 这里这种行为不是问题)。如果您从应用程序运行 SQL 服务,也许您可​​以通过临时使用操作系统资源来强制释放内存 - 但是,我不推荐这样做,也没有尝试过......
  • 我面临着类似的问题。但是一旦 SQL 服务器内存使用达到峰值。新的查询出现超时错误,除了重新启动 mssql 服务器之外别无他法。这里有什么问题?以及如何解决?
  • @Krunal - 你能弄明白吗?
【解决方案2】:

我也遇到了上述同样的问题。 但是在释放 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

【讨论】:

    【解决方案3】:

    我认为没有办法强制 SQL Server 释放内存。 但是,您可以限制内存使用量。

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

    MSDN

    【讨论】:

      【解决方案4】:

      老问题,但我想我会加两分钱。主要是对上述答案中的内容的重复,使用 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
      

      【讨论】:

        【解决方案5】:

        SQL 是一种高级声明性语言。它的目的不是让您像使用 C 等较低级别的编程语言编写代码那样参与诸如内存管理之类的细节。我想您会发现,如果它需要释放内存对于另一项任务,它会很快放手。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-05-18
          • 2011-01-23
          • 1970-01-01
          • 2015-06-10
          • 2016-12-24
          • 1970-01-01
          • 2011-09-29
          • 2011-09-13
          相关资源
          最近更新 更多