为什么这个简单的查询被授予如此多的内存?
-- Demo table
CREATE TABLE dbo.Test
(
TID integer IDENTITY NOT NULL,
FilterMe integer NOT NULL,
SortMe integer NOT NULL,
Unused nvarchar(max) NULL,
CONSTRAINT PK_dbo_Test_TID
PRIMARY KEY CLUSTERED (TID)
);
GO
-- 100,000 example rows
INSERT dbo.Test WITH (TABLOCKX)
(FilterMe, SortMe)
SELECT TOP (100 * 1000)
CHECKSUM(NEWID()) % 1000,
CHECKSUM(NEWID())
FROM sys.all_columns AS AC1
CROSS JOIN sys.all_columns AS AC2;
GO
-- Query
SELECT
T.TID,
T.FilterMe,
T.SortMe,
T.Unused
FROM dbo.Test AS T
WHERE
T.FilterMe = 567
ORDER BY
T.SortMe;
Run Code Online (Sandbox Code Playgroud)
对于估计 …
产生“Excessive Grant”执行计划警告的条件是什么?
查询内存授予检测到“ExcessiveGrant”,这可能会影响可靠性。授权大小:初始 5128 KB,最终 5128 KB,已用 16 KB。
<Warnings>
<MemoryGrantWarning GrantWarningKind="Excessive Grant"
RequestedMemory="5128" GrantedMemory="5128" MaxUsedMemory="16" />
</Warnings>
Run Code Online (Sandbox Code Playgroud) 前几天有人问我,如果 SQL Server 想要运行一个查询,而该查询被授予的内存多于实例可用的内存,会发生什么情况。我最初的想法是我可能会看到RESOURCE_SEMAPHORE等待并且查询永远不会开始。
我做了一些测试来试图找出答案。
我的实例以 4000MB RAM 启动:
EXEC sys.sp_configure N'max server memory (MB)', N'4000'
GO
RECONFIGURE WITH OVERRIDE
GO
Run Code Online (Sandbox Code Playgroud)
如果我然后运行我的(故意可怕的)查询:
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;
Run Code Online (Sandbox Code Playgroud)
执行计划显示授予的内存为 732,008KB。
然后,我将实例可用的内存设置为低于此数字,然后重新启动实例:
EXEC sys.sp_configure N'max server memory (MB)', N'500' /* a value lower than the previous memory …Run Code Online (Sandbox Code Playgroud) 我听说过关于并行选择查询的内存授予的相互矛盾的事情:
是哪个?
我有一个带有多个执行计划的查询,与第二个计划相比,授予一个计划的内存是巨大的
当嵌套循环联接的外部表具有将结果过滤为小输入的谓词时,会出现问题,但批处理排序似乎使用与整个外部表等效的基数估计值。这可能会导致感知到过多的内存授予,这在非常并发的服务器中可能会产生多种副作用,例如 OOM 条件、计划缓存驱逐的内存压力或意外的 RESOURCE_SEMAPHORE 等待。我们已经看到,匹配此模式的单个查询实际上可以在高端机器(1TB+ RAM)上获得几 GB 的授予内存。
到目前为止,一种选择是使用跟踪标志 2340 全局禁用此功能,如 KB 2801413 中所述。但是,在 SQL Server 2016 RC0 中,我们已更改行为以保持优化的优势,但现在最大授予限制基于在可用的内存授予空间上。这种改进也转化为更好的可扩展性,从某种意义上说,可以用更小的内存占用执行更多的查询。我们正在考虑将此行为反向移植到即将推出的已将此行为移植到 SQL Server 2014 Service Pack 2,并像往常一样为市场上的版本提供附加值。
这正是我所看到的,但是我使用的是 SQL Server 2016 Enterprise。
这些是执行计划
https://www.brentozar.com/pastetheplan/?id=SJ0mYAy0b
https://www.brentozar.com/pastetheplan/?id=BJzutC1R-
我的问题是
2个执行计划的原因是什么?
优化器正在使用顶部执行计划,我强迫它使用较低的计划,但过了一段时间它又回到顶部执行计划,有什么原因吗?
如何解决这个问题?这个问题导致应用程序崩溃(有很多RESOURCE_SEMAPHORE等待,应用程序变得无响应)?我应该使用提示:DISABLE_OPTIMIZED_NESTED_LOOP还是 Trace Flag 2340?
注意:我检查了 XML,两个计划都有 NestedLoops Optimized="false"
以下(在我的系统上,在 SQL Server 2016 和 2019 std 上测试)产生大量内存授予请求(3327 MB)
declare @wibble xml = '<wibble><wobble>1</wobble></wibble>'
select @wibble.query('//wobble[1]')
Run Code Online (Sandbox Code Playgroud)
我可以做些什么来减少补助金?
其他问题的图表适用于 100 万行的表。当绘制 10,000 行时,该图具有相当不同且更有趣的形状。
当列长度在 524 到 903 之间时,会出现一个平台期。
这种形状可以在我的工作和家用笔记本电脑上看到。(分别是 SQL Server 2017 CU27 和 2017 CU22、2019 CU8。两个盒子都有 16GB RAM。)
这让我认为这是经过调整的真正设计选择,而不是人工制品。
对于 SQL Server 2019 设置 BATCH_MODE_ON_ROWSTORE = OFF 几乎没有任何区别。除 t800 为 6688kB OFF 和 6656kB ON 外,所有大小所需的内存都是相同的。
这个图怎么会是这个形状呢?哪些考虑因素意味着三区域解决方案在中等行数(10,000 行)时是最佳的,但在较大行数(100 万行)时则不是最佳?
据我所知,SQL Sever 开发团队之外的任何人都无法最终说明该特定图形为何呈这种形状。但一般来说,从学术和行业经验来看,如果我开始为假设的 DBMS 编写内存管理模块,什么样的考虑会导致这种结果?
当我从两个连接表中选择列时,会获得巨大的内存授予(529808)。如果我单独查询每个表列,它的组合内存授予仅为 8008。
为什么组合的列列表有如此大的内存授予?或者我可以采取哪些步骤来找出答案?
问题:
我有几个查询需要大量内存授权(~7GB)。这些查询经常运行,这导致其他查询等待内存。所以我看到 RESOURCE_SEMAPHORE 等待类型。服务器信息:
我知道我已经发布了有关此服务器性能的类似问题。我试图从不同的角度看待事物或尝试以不同的方式解决问题。正如这篇文章中提到的,我有某种内存压力。现在我正在尝试修复查询中的问题或摆脱这个巨大的内存授权。
这是帖子中提到的查询的计划。
我了解到这SORT,HASH JOIN,EXCHANGE(parallel Distribute Stream and Parallel Re partition stream and Parallel Gather Stream)是消耗内存的迭代器,我在我的执行计划中看到了这些。
我怎样才能从这个查询中减少这个巨大的内存授权。?甚至我也很困惑内存压力是否是由于大量查询授予的巨大内存造成的。?
这是我使用 SQLServer 探查器捕获查询时的实际查询。
exec sp_executesql N'SELECT TOP (@p__linq__6)
[PJ2].[FormId] AS [FormId],
[PJ2].[TNUMId] AS [TNUMId],
[PJ2].[TNUMDateTime] AS [TNUMDateTime],
[PJ2].[TNUMEventNumber] AS [TNUMEventNumber],
[PJ2].[EventNumber] AS [EventNumber],
[PJ2].[SubUnit] AS [SubUnit],
[PJ2].[EventClass] AS [EventClass], …Run Code Online (Sandbox Code Playgroud) performance sql-server execution-plan memory-grant query-performance
memory-grant ×10
sql-server ×10
parallelism ×1
performance ×1
ssms ×1
t-sql ×1
warning ×1
xml ×1
xquery ×1