SQL Server最大和最小内存配置


8

在此用例中,最小内存和最大内存的正确设置是什么?

该服务器具有8GB内存,双Intel Xeon处理器,运行Windows Server 2008 R2 / SQL Server 2008 Standard Edition。它运行着多个数据库,大小从30GB到5GB不等。

最初,内存使用情况已设置为默认设置(最小= 0,最大= 2,147,483,647)。在这些设置上,大多数内存使用量已由sqlservr.exe占用,并且最终将需要每天或每两天重新启动服务器一次。它最初会正常运行,但一天之内就会在一些简单的操作(例如,使用主键查找记录)上超时。

我更改了最小值= 4,096和最大值= 6,144。这样只会占用1.4GB的内存。但是,现在所有四个cpus始终以50-60%cpu的使用率运行。尽管服务器要稳定得多,但执行任务所需的时间大约要长1/3。


购买更多的RAM,并将最大值保留为默认值。
Remus Rusanu

4
@RemusRusanu我假设你的意思分钟到默认!
Kin Shah

当人们忘记实践时,我们会遇到非常相似的用例和相似的问题(由于SQL抓住了所有操作系统,导致操作系统没有记忆)。我们的做法是使用0(最小值),一半可用(最大值)。
Paul

@kin no,我的意思是max。我应该说将最小值和最大值都保留为默认值,但是我从来不明白为什么有人会改变最小值……
Remus Rusanu 2013年

1
@RemusRusanu我认为这是一个错字,因为您拥有大量的内部知识+出色的答案。我不同意将“ 最大内存” 保留为默认值。
Kin Shah

Answers:


10

查看此特定服务器的RAM可用性,并且您正在运行从30GB到5 GB的几个数据库,则肯定需要此服务器上更多的RAM。

您没有提到这是一个独立实例,或者该服务器正在运行多个sql服务器实例。

对于具有8GB RAM的服务器,您的MAX内存设置似乎还可以。请参阅Glenn Berry提供的建议的最佳实践设置

我强烈建议您使用下面的PERFMON计数器为您的环境做一个基准,以获取良好的内存配置值:

  • SQL Server:缓冲区管理器\页面预期寿命
  • SQL Server:缓冲区管理器\页面读取数/秒
  • 物理磁盘\磁盘读取/秒
  • 内存\可用兆字节
  • SQL Server:内存管理器-服务器总内存
  • SQL Server:内存管理器-目标服务器内存

服务器总内存:当前分配给缓冲池的内存量,而不是 SQL Server的总内存量

目标服务器内存:与实例的最大内存相对应的缓冲池的理想大小。

注意:如果“总服务器内存”>“目标服务器内存”,则表明内存压力大。

下面的脚本将帮助您从sys.dm_os_ring_buffers-系统运行状况会话中找到内存不足的通知:

SELECT CONVERT (varchar(30), GETDATE(), 121) as [RunTime],
dateadd (ms, (rbf.[timestamp] - tme.ms_ticks), GETDATE()) as [Notification_Time],
cast(record as xml).value('(//Record/ResourceMonitor/Notification)[1]', 'varchar(30)') AS [Notification_type],
cast(record as xml).value('(//Record/MemoryRecord/MemoryUtilization)[1]', 'bigint') AS [MemoryUtilization %],
cast(record as xml).value('(//Record/MemoryNode/@id)[1]', 'bigint') AS [Node Id],
cast(record as xml).value('(//Record/ResourceMonitor/IndicatorsProcess)[1]', 'int') AS [Process_Indicator],
cast(record as xml).value('(//Record/ResourceMonitor/IndicatorsSystem)[1]', 'int') AS [System_Indicator],
cast(record as xml).value('(//Record/MemoryNode/ReservedMemory)[1]', 'bigint') AS [SQL_ReservedMemory_KB],
cast(record as xml).value('(//Record/MemoryNode/CommittedMemory)[1]', 'bigint') AS [SQL_CommittedMemory_KB],
cast(record as xml).value('(//Record/MemoryNode/AWEMemory)[1]', 'bigint') AS [SQL_AWEMemory],
cast(record as xml).value('(//Record/MemoryNode/SinglePagesMemory)[1]', 'bigint') AS [SinglePagesMemory],
cast(record as xml).value('(//Record/MemoryNode/MultiplePagesMemory)[1]', 'bigint') AS [MultiplePagesMemory],
cast(record as xml).value('(//Record/MemoryRecord/TotalPhysicalMemory)[1]', 'bigint') AS [TotalPhysicalMemory_KB],
cast(record as xml).value('(//Record/MemoryRecord/AvailablePhysicalMemory)[1]', 'bigint') AS [AvailablePhysicalMemory_KB],
cast(record as xml).value('(//Record/MemoryRecord/TotalPageFile)[1]', 'bigint') AS [TotalPageFile_KB],
cast(record as xml).value('(//Record/MemoryRecord/AvailablePageFile)[1]', 'bigint') AS [AvailablePageFile_KB],
cast(record as xml).value('(//Record/MemoryRecord/TotalVirtualAddressSpace)[1]', 'bigint') AS [TotalVirtualAddressSpace_KB],
cast(record as xml).value('(//Record/MemoryRecord/AvailableVirtualAddressSpace)[1]', 'bigint') AS [AvailableVirtualAddressSpace_KB],
cast(record as xml).value('(//Record/@id)[1]', 'bigint') AS [Record Id],
cast(record as xml).value('(//Record/@type)[1]', 'varchar(30)') AS [Type],
cast(record as xml).value('(//Record/@time)[1]', 'bigint') AS [Record Time],
tme.ms_ticks as [Current Time]
FROM sys.dm_os_ring_buffers rbf
cross join sys.dm_os_sys_info tme
where rbf.ring_buffer_type = 'RING_BUFFER_RESOURCE_MONITOR' 
--and cast(record as xml).value('(//Record/ResourceMonitor/Notification)[1]', 'varchar(30)') = 'RESOURCE_MEMPHYSICAL_LOW'
ORDER BY rbf.timestamp ASC

一些好的参考资料:


2
您有错误的总和目标比较方法,但是无论如何,都有更好的方法来确定服务器是否受到外部内存的压力。
保罗·怀特9

@paulwhite您能否再说明一下,以便我改善答案?感谢您的调查。
Kin Shah 2013年

这是一个独立的实例
sa555
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.