根据 Christian Bolton、Brent Ozar 等人关于 SQL Server 2008 Internals and Troubleshooting(从伊利诺伊州当地图书馆借来)的阅读书籍。我试图在 SQL Server 上寻求理解和确认,并在网络上进行大量搜索,如果有人我将不胜感激可以确认或更正我的理解。
每个需要查询内存授权的查询或操作都需要工作空间内存。在使用排序、哈希匹配连接、并行(不确定)、批量插入(不确定)、索引重建等的一般查询中,将需要查询工作区内存。
工作区内存是 SQL Server 缓冲池的一部分(它作为缓冲池的一部分分配),最大工作区内存是分配给缓冲池的内存的 75%。默认情况下,单个查询不能获得超过 25% 的工作区内存(在 SQL 2008/SQL 2012 中 - 由开箱即用的资源调控器默认工作负载组控制)。
寻求确认我的理解
1)考虑具有 48 GB RAM 和最大服务器内存配置为 40 GB 的系统,这是否意味着最大工作空间内存限制为 30 GB,并且单个查询无法获得超过 10 GB 的工作空间内存(查询内存)。因此,如果您有一个错误的查询正在处理 10 亿行正在执行大规模哈希联接并且需要超过 10 GB 的内存(工作空间内存),它甚至会关心通过这个内存授予队列还是立即溢出到磁盘?
2) 如果执行大规模排序操作的查询已分配 5 MB 的工作空间内存,并且在查询执行期间,如果查询优化器意识到由于统计信息错误或缺少索引,该查询实际上需要30 MB的工作空间内存将立即溢出到 tempdb。即使系统在执行期间有大量可用的工作空间内存,一旦查询在执行期间超过了授予的工作空间内存,它也必须溢出到磁盘。我的理解正确吗?
它不是那样工作的。一旦选择了需要内存授权的计划,查询必须获得授权才能通过队列。溢出,如果有的话,发生在执行周期的很晚。查询不能决定在没有授权的情况下继续进行,而是“溢出”。它必须获得授权,并在此基础上开始执行。如果授权不足(由于估计错误或由于获得的授权比请求的低得多),则查询将被迫溢出。
严格来说,它不是优化器,而是查询执行。查询优化器在决定计划方面只有发言权,但是一旦选择了计划并启动执行,优化器就无法进行。此外,“缺失索引”在这里没有任何作用。缺少索引可能会强制执行错误的计划,但它不会影响该“错误”计划的执行方式,因为该计划的构建考虑了实际存在的索引,因此它确切地知道它可以做什么和不能做什么。溢出几乎总是由于错误的估计而发生,即。优化器和执行中糟糕的统计数据或糟糕的基数估计算法(如果你深入研究细节,它会变得非常复杂,所以我会在这里停下来)。
不幸的是,是的。但是,优化器应该提出一个利用可用 RAM 的计划。
我推荐阅读Understanding SQL server memory grant,这是关于该主题的最佳信息。