Ian*_*oyd 0 sql-server sql-server-2012 buffer-pool
SQL Server 使用 34 GB RAM。但当查询内存消耗报告、缓冲池大小和即席查询大小时,加起来只有 2 GB 左右。另外 32 GB RAM 有何用途?
\n先发制人:“您应该限制 SQL Server 可以使用的 RAM 量。” 可以说它的上限是x。这只是将我的问题改为“其他xGB 的 RAM 在做什么?”
我有一个消耗 32 GB RAM 的 SQL Server 实例:
\n\n这不是 32 GB虚拟内存;它实际上消耗了 32 GB物理内存(在 RAM 芯片上)——称为“工作集”。
\n而且它不像是与其他进程共享的。本质上所有这些都是 SQL Sever 私有的:
\n\n它用那么多内存做什么?
\n因此,我们按数据库查询内存使用情况 - 因为缓冲池缓存数据库中的页面:
\n--Memory usage server wide\n;WITH src AS\n(\n SELECT\n database_id,\n COUNT_BIG(*) AS db_buffer_pages\n FROM sys.dm_os_buffer_descriptors\n --WHERE database_id BETWEEN 5 AND 32766\n GROUP BY database_id\n)\nSELECT\n CASE [database_id] WHEN 32767 THEN \'Resource DB\' ELSE DB_NAME([database_id]) END AS [Database Name],\n db_buffer_pages AS BufferPages,\n db_buffer_pages /128.0 AS BufferMB\nFROM src\nORDER BY db_buffer_pages DESC\nOPTION(RECOMPILE, MAXDOP 1);\nRun Code Online (Sandbox Code Playgroud)\n32 GB 中总共4.5 MB 。
\nTempDB 使用最多(1.4 MB),其余的从那里开始下降:
\n\n32 GB 中的 5 MB - 并不占太多
\n是的,这可能看起来很低 - 但这可能是因为我DBCC DROPCLEANBUFFERS先打电话。
接下来我们查询查询计划缓存。所有这些 T-SQL 语句都必须编译成一个巨大的计划,并且这些计划缓存在 RAM 中。
\n--Server-wide memory usage of plan cache\nSELECT\n [cacheobjtype], ObjType,\n COUNT(1) AS Plans,\n SUM(UseCounts) AS UseCounts,\n SUM(CAST(size_in_bytes AS real)) / 1024.0 / 1024 AS [SizeMB]\nFROM sys.dm_exec_cached_plans\n--where [cacheobjtype] = \'Compiled Plan\' and [objtype] in (\'Adhoc\', \'Prepared\')\nGROUP BY CacheObjType, ObjType\nORDER BY SizeMB DESC\nOPTION(RECOMPILE, MAXDOP 1)\nRun Code Online (Sandbox Code Playgroud)\n现在我们可以看到有多少内存用于存储各种查询计划:
\n| 缓存对象类型 | 对象类型 | 计划 | 使用计数 | 大小MB |
|---|---|---|---|---|
| 编制计划 | 过程 | 3 | 4 | 0.21875 |
| 解析树 | 用户选项卡 | 1 | 1 | 0.03125 |
| 解析树 | 看法 | 1 | 6 | 0.0234375 |
总共250 KB -远远低于缺失的 32 GB。
\n\n\n注意:是的,这可能看起来很低 - 但这可能是因为我
\nDBCC FREEPROCCACHE先打电话。
上述查询显示了以下人员使用的 RAM:
\n这就是全部了。但 SQL Server 确实提供了内存消耗报告:
\n\n\n该报告提供有关实例内组件内存消耗的详细数据
\n
旁白:“没有”
\n该报告有点难以阅读:
\n\n但最终的分解是:
\n总共为:556,424 KB \xe2\x86\x92 544 MB
\n即使我们将其四舍五入到 1 GB:它仍然与 32 GB 相去甚远。
\n那么内存去哪儿了呢?
\n是的,我可以将 SQL Server 的 RAM 限制为 25 GB。但这只会将我的问题改为:
\n\n\nSQL Server 使用 25 GB RAM 的目的是什么?内存去哪儿了?
\n
因为这对我来说听起来很像内存泄漏。
\n可以查询服务器的正常运行时间(创建 tempdb):
\n--Use creation date of tempdb as server start time\nRun Code Online (Sandbox Code Playgroud)\nSELECT SERVERPROPERTY(\'SERVERNAME\') AS ServerName, create_date AS ServerStartedDate FROM sys.databases WHERE NAME=\'tempdb\';
\n2021-12-21 15:46:26.730SELECT * FROM sys.assemblies\nRun Code Online (Sandbox Code Playgroud)\n| 姓名 | 主体 ID | 程序集 ID | clr_名称 | 权限集 | 权限集描述 | 可见 | 创建日期 | 修改日期 | 是用户定义的 |
|---|---|---|---|---|---|---|---|---|---|
| Microsoft.SqlServer.Types | 4 | 1 | microsoft.sqlserver.types,版本=11.0.0.0,文化=中性,publickeytoken=89845dcd8080cc91,处理器架构=msil | 3 | 不安全访问 | 1 | 2012-02-10 20:15:58.843 | 2012-02-10 20:15:59.427 | 0 |
select provider, provider_string from sys.servers
| 提供者 | 提供商字符串 |
|---|---|
| SQLNCLI | 无效的 |
| 微星DXS | 无效的 |
| 搜索.collatordso | 无效的 |
| DB2OLEDB | 包集合=\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\ x92;网络地址=\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92\xe2\x96\x92;网络端口=50000;连接超时=0; |
如果您在检查内存使用情况之前运行DBCC DROPCLEANBUFFERS,它只会显示 SQL Server 使用的少量内存,但运行此命令不会将释放的内存释放回操作系统。
DBCC DROPCLEANBUFFERS将从缓冲池中删除所有干净的缓冲区,但是,sqlservr.exe 将保留之前分配的内存,并在执行后立即重新使用该内存以开始在缓冲池中分配页面DBCC DROPCLEANBUFFERS。如果您在服务器上遇到内存不足的情况,sqlservr.exe可能会开始将内存释放回操作系统,除非您启用了“锁定内存页面”。
这些内存消耗查询/报告不会立即报告任何感兴趣的内容,DBCC DROPCLEANBUFFERS因为为进程分配的内存现在基本上未使用。要了解 SQL Server 如何使用其内存分配,请在运行之前运行这些查询/报告DBCC DROPCLEANBUFFERS(实际上根本不应该在生产服务器上运行)。
注意:您可以通过在 后删除最大服务器内存来强制 SQL Server 将内存释放回操作系统DBCC DROPCLEANBUFFERS。这通常不是即时的,但由于大部分未使用的页面分配给 sqlservr.exe 进程,它应该相当快地释放内存。
| 归档时间: |
|
| 查看次数: |
4924 次 |
| 最近记录: |