对于我的一台具有以下配置的服务器,我不断收到低 PLE 的警报,每天的范围在 20-400 和平均 90-100 之间:
服务器:SQL Server 2008R2
数据库:系统和 2 个用户数据库,数据库的最大大小为 54 GB
内存:16GB
最大服务器系统内存:12.24 GB
一旦我得到内存压力的提示,我就使用 RAMMAP 来查找内存使用情况,并发现使用 13.8 GB 的私有进程表明对较低内存压力的进一步怀疑:
根据 Paul Randal 的博客,我分析并发现其中一个用户数据库 A 使用了 8 GB RAM:此外,我分析了一段时间,发现 tempdb 平均使用 3-4 GB RAM
然后通过进一步调查,我发现在那个数据库 A 中有一个表有一个聚集索引,平均消耗 6-6.5 GB 的内存。(碎片不是问题,因为它已经过检查)
现在从这里我不确定如何进行?我应该去创建丢失的索引还是可以删除未使用的索引?或者在做出任何结论之前我还需要深入研究其他内容。
请建议!
首先,图片中的 SQL Server
SQL Server 2008 R2 RTM
不受 Microsoft 的任何支持,请应用SQL Server 2008 R2 SP3至少获得扩展支持我不认为因此有任何问题,这是完全正常的看这个你不能得出任何结论。
我猜这张表是数据库中最大的表,它占用了缓冲池的大部分。我不能直接说为什么表再次持有如此多的内存
you should first apply SP3 to rule out any possibility of leaks and then move with troubleshooting
。对于具有 12 G RAM 的系统,PLE 应该在 900 左右。但是既然你说它总是在 300-400 左右,这让我觉得 SQL Server 必须努力工作并且由于内存压力而经常将页面从内存移出到磁盘。要确认内存压力,您必须依赖其他计数器而不仅仅是 PLE,您可以打开 perfmon 并添加以下计数器。最好创建一个数据收集器集来监视性能计数器
SQLServer:memory Manager--Target Server Memory:这是 SQL Server 试图获取的内存量。
SQLServer:memory Manager--Total Server memory 这是 SQL Server 已获取的当前内存。
(理想情况下目标值应小于或等于总计)
Page reads/sec – 每秒发出的物理数据库页面读取数。此统计信息显示所有数据库的物理页面读取总数。由于物理 I/O 非常昂贵,您可以通过使用更大的数据缓存、智能索引和更高效的查询,或者通过更改数据库设计来最大限度地降低成本
Free Pages – 所有空闲列表中的页面总数(空闲列表跟踪缓冲池中当前未分配给数据页的所有页面,因此可立即使用)。毫无疑问,这个值应该很高
页面预期寿命——页面在没有引用的情况下保留在缓冲池中的秒数 > 如果您有 NUMA 系统分析每个节点的 PLE,如本文所述
Free List Stalls/sec – 每秒必须等待空闲页面的请求数。理想情况下,档位应尽可能为零或尽可能少
SQLServer:Memory Manager--Memory Grants Pending:如果您在缓冲池中看到内存授予挂起,则您的服务器正面临 SQL Server 内存紧缩,增加内存是个好主意。对于内存授予,请阅读这篇文章:如果您看到非零值的内存授予挂起且 PLE 低和空闲列表停顿高,您肯定有内存压力,应该考虑提供更多 RAM。
请注意:上述计数器的值应至少收集 3-4 小时,并且在系统负载相对非常高时收集。如果可能的话,在收集值之前请刷新缓冲区缓存,虽然我不是说你要这样做,但我知道对于 Prod 系统这是不可能的。如果你能产生价值,我可以为你分析。
我不知道系统的工作量,只是给你选择如何进行。您还应该分析代价高昂的查询。寻找一个涉及散列连接和排序的。
一个在大表上进行大量连接和扫描的错误查询具有所有能力,可以使 PLE、内存授予、空闲列表停止等计数器值,这让你相信它的内存压力,是的,但原因是糟糕的查询和缺少索引和不正确的加入。你也应该考虑这一点。
编辑:
根据上述计数器的要求,来自性能数据收集器的输出
以下是一些值得注意的点
目标服务器内存和总服务器内存在
there value were equal
整个数据收集过程中(从上午 10 点到下午 3 点)保持不变。这表明 SQL Server 数据库引擎对其当前的内存需求感到满意未决的内存授予是
always zero
。Free List stalls/Sec 为
always zero
. 这意味着没有请求必须等待空闲页面从下午 2 点 15 分到下午 3 点 18 分,PLE 有相当大的减少,同时页面读取/秒非常高,这让我相信一些查询/进程在下午 2:00 之后开始,这需要太多的内存页面和因此导致缓冲池中出现一系列活动。
您需要找出什么查询在下午 2:00 之后运行并且它仍在运行,所以这让我觉得 process.job 从下午 2:00 开始。此进程/作业/查询正在尝试读取太多页面,这导致 lazywriter 刷新太多页面,因为查询正在为此类页面请求空间
可能是这样的查询缺少索引,可能是由于统计数据偏斜而创建了一个错误的计划,可能是需要编写查询来获取/读取数据的子集而不是整个数据。