我正在运行支持供应商软件的最新补丁/CU 级别的本地 SQL Server 2017 Enterprise,这将在稍后变得重要。
服务器统计:
- 虚拟机(内存已固定)
- Windows Server 2016 数据中心
- 16 个虚拟 CPU
- 192 GB RAM(179 GB 分配给 SQL Server)
- 30 GB 页面文件(我宁愿这个不存在,但这不是我赢得的战斗)
- 托管 5 个用户数据库,其中 1 个大小约为 4TB
- 供应商要求的服务器默认值为 1
max degree of parallelism
如上所述,该系统支持流行的供应商平台,虽然供应商在自定义索引或其他透明数据模型调整方面做得很好,但他们往往不赞成需要调整其应用程序代码的功能更改(原因很明显,因为这会影响成千上万的客户)。
我遇到的情况是这个供应商应用程序运行长时间运行的row mode
查询,这些查询将在其应用程序代码中逐项处理的项目列表排队。如果我们允许这些查询可以(并且确实)运行数天甚至数周(ASYNC_NETWORK_IO
如预期的那样显示等待)。当这些查询被启动时,他们请求的数量与他们真正需要SerialDesiredMemory
的数量相比是巨大的。SerialRequiredMemory
结果是MEMORYCLERK_SQLQERESERVATIONS
内存管理员中的请求/授予的内存远远超过了使用的内存。例如:
-- What amount of query execution memory is asked for and used
SELECT SUM(granted_memory_kb) / 1024 AS granted_memory_mb
, SUM(requested_memory_kb) / 1024 AS requested_memory_mb
, SUM(used_memory_kb) / 1024 AS used_memory_mb
, (SUM(granted_memory_kb) - SUM(used_memory_kb)) / 1024 AS excess_memory_grant_mb
FROM sys.dm_exec_query_memory_grants
OPTION (RECOMPILE)
回报:
这绝对是可怕的,这是在启用资源池RESOURCE GOVERNOR
并将REQUEST_MAX_MEMORY_GRANT_PERCENT
这些查询降至% 之后,尽管根据我所看到5
的情况,我可能会一直将其降低到SQL 2017 的最小值。1
REQUEST_MAX_MEMORY_GRANT_PERCENT
我的问题是,当我被困在 SQL 2017 时,除了进一步将资源池的价值降低到1
%之外,我还能做些什么来限制查询执行计划中浪费的 RAM 数量?
由于这是一个供应商应用程序,因此查询计划指南可能是一种选择,但调整MAX_GRANT_PERCENT
并没有给我带来任何好处,而不仅仅是调整REQUEST_MAX_MEMORY_GRANT_PERCENT
资源池中的值。我可以在计划指南中做些什么来强制batch mode
执行,希望这会触发 SQL 2017 中提供的批处理模式内存反馈功能?同样,由于这是我正在使用的供应商应用程序代码,因此我无法更改查询,因此标准的汤姆愚弄方法可能在这里不起作用。
升级到 SQL 2019(或者最好是 SQL 2022)是显而易见的答案,因为它使我可以访问在这种情况下可以使用的许多功能,例如行模式内存反馈和浮点值REQUEST_MAX_MEMORY_GRANT_PERCENT
,但是还有其他可用的选项吗使用 SQL 2017 我还没有接触过?如果没有,那很好,我只是想用尽我还没有想到的任何出色的选择。
如文档所述,即使在 SQL Server 2017 上,查询提示
MAX_GRANT_PERCENT
也允许浮点值低至 0.0,因此这仍然是一个选项。db<>小提琴
所以你可以为此创建一个计划指南