AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 319327
Accepted
SEarle1986
SEarle1986
Asked: 2022-11-08 15:46:06 +0800 CST2022-11-08 15:46:06 +0800 CST 2022-11-08 15:46:06 +0800 CST

SQL Server 是否可以为查询授予比实例可用的更多内存

  • 772

前几天有人问我,如果 SQL Server 想要运行单个查询,而该查询被授予的内存比实例可用的内存多,会发生什么情况。我最初的想法是我可能会看到RESOURCE_SEMAPHORE等待并且查询永远不会开始。

我做了一些测试试图找出答案。

我的实例在 4000MB RAM 上启动:

EXEC sys.sp_configure N'max server memory (MB)', N'4000'
GO
RECONFIGURE WITH OVERRIDE
GO

如果我然后运行我的(故意可怕的)查询:

USE StackOverflow
SELECT      CONVERT(NVARCHAR(4000), u.DisplayName) AS DisplayName,
            CONVERT(NVARCHAR(MAX), u.DisplayName) AS Disp2,
            CONVERT(NVARCHAR(MAX), u.DisplayName) AS Disp3
FROM        dbo.Users AS u
            JOIN dbo.Posts p
                ON LTRIM(u.DisplayName) = LTRIM(p.Tags)
WHERE       u.CreationDate >= '2008-12-25'
            AND u.CreationDate < '2010-12-26'
ORDER BY    u.CreationDate;

执行计划说授予的内存是 732,008KB。

然后我将我的实例可用的内存设置为低于此数字,然后重新启动实例:

EXEC sys.sp_configure N'max server memory (MB)', N'500' /* a value lower than the previous memory grant */
GO
RECONFIGURE WITH OVERRIDE
GO

我再次运行查询,发现它被授予的内存比以前少(93,176KB),但计划实际上是不同的形状。

然后我再次运行查询并使用查询提示强制原始计划查看授予的内存:

USE StackOverflow
SELECT      CONVERT(NVARCHAR(4000), u.DisplayName) AS DisplayName,
            CONVERT(NVARCHAR(MAX), u.DisplayName) AS Disp2,
            CONVERT(NVARCHAR(MAX), u.DisplayName) AS Disp3
FROM        dbo.Users AS u
            JOIN dbo.Posts p
                ON LTRIM(u.DisplayName) = LTRIM(p.Tags)
WHERE       u.CreationDate >= '2008-12-25'
            AND u.CreationDate < '2010-12-26'
ORDER BY    u.CreationDate
OPTION (RECOMPILE, USE PLAN N'<xml here>'

我发现查询现在使用原始计划,但获得与其编译的计划(93,168KB)非常相似的内存授权 -强制实际计划

这似乎反驳了我的理论,即我会看到RESOURCE_SEMAPHORE等待,并表明存在某种机制可以防止 SQL Server 授予比查询可用的内存更多的内存(这似乎非常明智!)顺便说一下,如果我在同时会话中运行查询两次500MB 服务器设置,然后两个会话都会RESOURCE_SEMAPHORE等待似乎不确定的内容。

我可以MaxQueryMemory在计划中看到,这似乎是阻止 SQL Server 授予比查询可用的更多内存的原因。

是否可以为单个查询授予比实例可用的内存更多的内存?如果不是,是MaxQueryMemory什么原因导致 SQL Server 分配的内存超出了可用内存?这个数字是如何计算的?

注意 - 我的 StackOverflow 数据库处于 130 兼容级别

sql-server
  • 1 1 个回答
  • 1199 Views

1 个回答

  • Voted
  1. Best Answer
    Erik Darling
    2022-11-08T16:33:46+08:002022-11-08T16:33:46+08:00

    默认情况下,SQL Server 允许任何查询使用最多 25% 的最大服务器内存来授予内存,但实际上它通常接近 20%。

    资源管理者对此有话要说:

    坚果

    但是在我的最大服务器内存设置为 90GB 的演示 VM 上,我可以获得的最高单查询内存授予是 17GB,而不是 22GB。

    WITH
        c AS 
    (
    SELECT
        c.*,
        n = 
            ROW_NUMBER() OVER 
            (
                PARTITION BY 
                    c.PostId 
                ORDER BY 
                    c.Score DESC
            )
    FROM dbo.Comments AS c
    )
    SELECT
        c.*
    FROM c
    WHERE n = 0;
    

    这是它的部分计划:

    坚果

    使用sp_PressureDetector,您可以获得有关 SQL Server 内存使用情况的大量信息。为了将其保留在内存授权中,这就是我运行上述查询时发生的情况:

    坚果

    直到我运行了四个查询副本,一个查询才在资源信号量的队列中等待:

    坚果

    等待信息:

    坚果

    考虑它的一般方式是 SQL Server 会将大约 75% 的最大服务器内存分配给请求授权的查询。

    在这种情况下,68GB 的​​内存可用于 90GB 以外的赠款。由于第四个查询将超过约 75% 的标记,因此必须等待。

    一般来说,总授权加上 50% 必须可用于立即授权的内存。如果没有,它会等待,有时直到强制降低授权(查看 中的forced_grant_count列sys.dm_exec_query_resource_semaphores)

    您可以从以下来源更详细地了解 SQL Server 通常如何确定信号量队列和内存授予的优先级:

    • 在 SQL Server 中查询内存授予和资源信号量
    • 启用资源调控器来修复内存授予
    • 查询调优精通:禅与工作区记忆的艺术

    请记住,我的回答仅针对传统的行模式和行存储工作负载。添加批处理模式和列存储索引将改变一些行为,特别是在尊重最大服务器内存以及需要内存授权的情况下。

    使用行模式,您将看到授予查询的内存授予的最常见位置是查询计划具有以下功能时:

    • 排序
    • 散列连接或聚合
    • 优化的嵌套循环

    即使查询计划中没有 DML 请求排序来执行压缩,对列存储索引的插入也会要求内存。

    • 16

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve