Gok*_*han 5 sql-server memory execution-plan
我们正在运行SQL Server 2014 Enterprise Sp2使用1.5TB的内存和64 cores。17 GB这个单线程查询的内存接近,使用的最大内存是2.2gb,即使散列连接有足够的可用内存,它似乎没有使用它并溢出到磁盘。知道为什么吗?先感谢您。
SQLPerformance 中发布的相同问题。查询计划和图像张贴在那里
我想了解内存分数。它显示哈希连接具有 52.48% 的内存授权(总计 17GB+),接近 9GB。但是该计划使用的最大内存要少得多,即 2.2+GB,并且 Hash join 是此查询中唯一的溢出。我对内存分数有什么遗漏,它们不准确吗?
17GB 内存授予贯穿整个查询。这 17GB 并没有全部提供给单个运营商。每个操作员获得总授权的一小部分,并且在查询执行期间不会动态重新分配该金额。
如果您进入查询的 XML 并搜索 MemoryFractions(或将鼠标悬停在 Plan Explorer 中的运算符上),您将看到有关分配给每个运算符的分数的更多信息。
它显示连接的输入端获得 52.48%,但不是输出端。如果您有更多内存来处理来自操作符的数据,您将溢出到磁盘。
为避免溢出,调整索引,调整查询,使用 2016 年新的最小内存授予提示等。
SQL Server 使用每个内存消耗运算符的输入和输出内存分数作为在查询执行期间评估内存授予重用机会的一部分。
哈希内连接在其输入阶段与哈希反半连接共享内存授权(而内连接正在读取行以构建其哈希表)。两个输入内存分数的总和是 0.524805(内连接)加上 0.475195(反半连接)= 1(整个内存授予的分数)。
然而这并不能意味着散列内连接可以消耗0.524805 * 17,060,288KB ~= 8,952,960KB尽管溢出警告文字说的话。这是因为在哈希内连接生成行时,相同的哈希表仍然存在。在执行的这个阶段,它与节点 11 处的 Sort 共享内存授权,后者正在读取行。这种并发执行运算符的组合由内部散列连接的输出内存部分捕获。
内部散列连接的输出内存分数是 0.0648054。将此添加到排序的输入分数 (0.876515) 和反半连接的输出分数 (0.0586793) 再次总和为 1。
内部散列连接的输出内存分数是 0.0648054,它只允许0.0648054 * 17,060,288 = 1,105,598KB内存授予。哈希表必须适合这个内存量,否则会溢出。溢出文本中报告的运行时使用的内存为 1,677,120KB - 授予的 1,105,598KB 加上溢出到tempdb 的79,696 个 8KB 页。
基本点是内存授予计算与数据的估计大小(有时是唯一值的数量)成正比。行数(基数)和平均行大小都很重要。如果这些是错误的,内存消耗操作符可能会溢出。
所有适用于提高基数/密度/平均行大小估计的正常操作都可能适用,这是不可能从匿名计划中说出来的。
我更喜欢采用列存储和批处理模式。除了通常的好处外,它还允许排序和散列动态获取额外的内存(可能需要记录和支持的跟踪标志)。
我在 SQLPerformance.com Q & A 上的复制问题上发布的完整答案的摘录
| 归档时间: |
|
| 查看次数: |
1564 次 |
| 最近记录: |