我们正在sys.dm_os_buffer_descriptors
使用以下查询查看
select
d.[name] [Database_Name],
(count(file_id) * 8) / 1024 [Buffer_Pool_Size_MB],
sum(cast(free_space_in_bytes as bigint)) / 1024 / 1024 [Free_Space_MB]
from sys.dm_os_buffer_descriptors b
join sys.databases d on
b.database_id = d.database_id
group by d.[name]
order by [Buffer_Pool_Size_MB]
对于我的一个数据库,它显示 [Buffer_Pool_Size_MB] = 77325 MB,并且 [Free_Space_MB] = 15849 MB
因此,缓冲池中大约 20% 的页面空间是空的。好像很浪费资源
问题:
- 这是一个问题吗?
- 如何
free_space_in_bytes
减少数量? - 在我们的情况下还有其他需要调查/查看的事情吗?
也许,也许不是。如果您的数据库仅占服务器最大服务器内存的 80%,那么这就是我期望看到的。
如果您的数据多于 RAM,则可用空间可能是由于其他要求内存的东西。其他可能是查询、CHECKDB、索引重建等的内存授予。
它也可能代表 Windows 和 SQL Server 之间的内存争斗。当您没有设置最大服务器内存来为 Windows 提供 10% 的内存十分之一以便它可以正常运行时,通常会发生这种情况。
之后,其他东西占用了内存,它要么没有被缓冲池重新使用,要么各种其他东西继续使用可以被缓冲池使用的内存。
如果您的数据库占最大服务器内存的约 80%,则什么也没有。
如果他们不这样做,您可以:
添加内存 通常会有所帮助,如果您添加足够的内存以缓存最常查询的对象并为需要它们的进程提供内存授权。弄清楚这个数字是留给你的练习。没有通用的计算,但一个好的起点是 RAM 占服务器数据的 50%。简单来说:如果你有 10GB 的数据,就有 5GB 的 RAM。
让其他东西要求更少的内存归结为弄清楚还有什么东西在要求内存,并适当地调整这些东西。
是的!查看被盗页面计数器:
这可以告诉您 SQL Server 从缓冲池中获取了多少内存并分配给了其他东西。
您还可以查看 SQL Server 是否必须强制任何查询内存授予:
由于您使用的是 SQL Server 2017,因此可以使用sp_BlitzCache:
EXEC sp_BlitzCache @SortOrder = 'memory grant';
这将向您显示要求最大内存授予的查询。当然,如果您的服务器内存非常低,您的计划缓存数据可能会很糟糕,因为那里的周转率可能非常高。如果是这种情况,请在此处停止并添加内存,然后再继续。
如果已打开,您可以尝试使用 Query Store。Proc 可从与上述相同的链接获得。
EXEC sp_BlitzQueryStore @DatabaseName = 'Your Important Database';
然后在结果中寻找“内存授予”模式。对于那些带回的查询,请在计划中查找排序和哈希。这些通常代表索引或查询调整机会。如果您需要帮助调整这些问题,请随时将它们作为新问题发布。不要把它们粘在这个上面。
而且,当然,也可能是您从不使用该内存。不过,我不会管它,因为有一天你可能会增长到那 20%。