为什么查询大型数据库表时 sys.dm_os_buffer_descriptors 报告的内存与最大服务器内存不匹配?(表大小>最大内存)

var*_*ble 2 sql-server sql-server-2019

我的 SQL 2019 enterprise 系统内存为 180GB,最大 SQL Server 内存配置为 160GB。

有 3 个大型数据库,每个数据库大约 450GB。其他的是较小的数据库。

当我运行以下查询时:

SELECT
    databases.name AS database_name,
    COUNT(*) * 8 / 1024 AS mb_used
FROM sys.dm_os_buffer_descriptors
INNER JOIN sys.databases
ON databases.database_id = dm_os_buffer_descriptors.database_id
GROUP BY databases.name
ORDER BY COUNT(*) DESC;
Run Code Online (Sandbox Code Playgroud)

输出是:

Db1 83443
Db2 35665
Db3 20112
Db4 3559
Db5 2236
Tempdb 988
Msdb 670
Ssisdb 21
Master 2
Model 0
Run Code Online (Sandbox Code Playgroud)

以上合计为146696=143GB。

我并行安排了 3 个代理作业,1 个作业目标 1 db(针对 db1、db2 和 db3)。该作业对一些最大的数据库表一一执行 select *。我执行 SELECT * 的所有表的总大小约为 250GB。

我知道 SQL 服务器应该消耗与最大内存设置中配置的一样多的内存。

当我在代理作业运行时多次运行上述查询时,我观察到 Db1、Db2、Db3 的内存增加和减少,并再次增加/减少。

减少的事实让我认为存在内存压力,因为从内存中删除了哪些页面,以便为其他数据库中的页面腾出空间。

然而令我困惑的是,上述查询输出的总大小始终在 135GB 到 145GB 左右。因此始终有大约 15GB 到 25GB 的备用 RAM。这违背了 SQL 占用尽可能多的内存的想法,我想问:

  1. 为什么上面的 SQL 查询显示随着代理作业的进展,db1、db2、db3 的内存使用量减少/增加/减少,即使总缓冲区利用率仅为 135-145GB 左右?不是应该只有当总利用率达到 160GB 左右时才会出现下降吗?

  2. SQL Server 缓冲区(上面显示的查询)不应该消耗整个 160GB 内存吗(因为被查询的表大约有 250GB)?

  3. 是否有一个查询来检查按数据库和其他因素划分的 SQL 最大内存设置值利用率有多少?

Str*_*DBA 6

在 SQL 2012 之前,最大内存设置仅影响缓冲池。2012 年及以后的行为有所不同。 SQL Server 2012 中的内存配置和大小调整

您遇到的 15-25 GB 未计算内存正在被缓冲池以外的其他东西使用。dmvsys.dm_os_memory_clerks提供内存使用情况的准确细分。