在缓冲区缓存中没有足够空间的情况下,SQL Server如何处理查询的数据?


10

我的问题是,SQL Server如何处理需要将比可用空间更多的数据拉入缓冲区缓存的查询?该查询将包含多个联接,因此结果集在磁盘上已经不存在该格式的结果,因此需要编译结果。但是即使在编译之后,它仍然需要比缓冲区高速缓存中可用空间更多的空间。

我举一个例子。假设您有一个SQL Server实例,总共有6GB的可用缓冲区高速缓存空间。我运行具有多个联接的查询,该联接读取7GB数据,SQL Server如何响应此请求?是否将数据临时存储在tempdb中?它会失败吗?它是否仅执行一次从磁盘读取数据并一次编译段的操作?

此外,如果我尝试返回7GB的总数据会发生什么,这是否会改变SQL Server的处理方式?

我已经知道解决此问题的几种方法,我很好奇SQL Server在按要求运行时如何在内部处理此请求。

另外,我确定此信息存在于某处,但我一直没有找到它。


1
用外行术语来说,SQL Server将把工作表及其自身内部处理的结果存储在tempdb中。在需要时从磁盘读取页面。页面将一直保留在内存中,直到被迫退出页面,或者当SQL准备将它们提交到磁盘时。这是当您运行大型查询时,tempdb将会增长。我已经看到查询使系统崩溃,因为tempdb可以不受限制地增长,并占用了驱动器上的所有剩余空间。我知道这不是100%准确,只是尝试简单地解释一下。使用数据的部分不是管理数据位置的部分
datagod

Answers:


13

页面将根据需要读入内存,如果没有可用的可用内存,则最早的未修改页面将替换为传入页面。

这意味着,如果执行的查询所需要的数据量超出了内存容量,那么许多页面的内存寿命将非常短,从而导致大量I / O。

通过查看Windows Performance Monitor中的“页面预期寿命”计数器,可以看到这种效果。看看https://sqlperformance.com/2014/10/sql-performance/knee-jerk-page-life-expectancy有关计数器一些伟大的细节。

在注释中,您特别询问了查询结果大于可用缓冲区空间时会发生什么。以最简单的示例为例select * from some_very_big_table;-假设表为32GB,并且max server memory (MB)配置为24GB。所有32GB的表数据将一次被读入页面缓冲区的页面中,并被锁存,格式化为网络数据包,然后通过网络发送。这是逐页进行的;您可能同时运行300个这样的查询,并且假设没有阻塞发生,则每个查询的数据将被读取到页面缓冲空间中,一次读取一个页面,并尽可能快地将其放入网络中请求并使用数据。一旦将每个页面上的所有数据发送到网络上后,该页面便会解锁,并将很快被磁盘上的其他页面替换。

在更复杂的查询的情况下(例如,汇总来自多个表的结果),页面将按照查询处理器的要求完全按照上述方式拉入内存。如果查询处理器需要临时工作空间来计算结果,则在编译查询计划时会先知道该信息,并将从SQLOS请求工作空间(内存)。SQLOS将在某个时候(假设它没有超时),将该内存分配给查询处理器,然后查询处理将恢复。如果查询处理器在估计要从SQLOS请求多少内存方面出错,则可能需要执行“溢出到磁盘”操作,其中数据以中间形式临时写入tempdb。一旦将已写入tempdb的页面写入tempdb,将为其释放闩锁,以腾出空间将其他页面读入内存。最终,查询过程将返回到tempdb中存储的数据,使用闩锁将其分页到缓冲区中标记为空闲的页面。

毫无疑问,上面的摘要中我缺少很多技术细节,但是我认为这抓住了SQL Server如何处理超出内存容量的更多数据的本质。


出于好奇,什么样的查询正在提取7GB的数据?我希望这是一个批处理过程。
datagod

可能不是很多,但您是对的,希望它将是一个批处理过程。我很好奇SQL如何处理该请求
Dustin

5

在这种情况下,我无法说出您的查询将执行什么操作,但是SQL Server根据需要多少有几种选择。

  • 数据可以“溢出”到TempDB,这将使用您的磁盘
  • 旧页面可以从缓冲区缓存中推出
  • SQL Server可以加载一些页面以缓存缓存,使用它们,然后在其中旋转新页面

找出可能发生的事情的最佳方法是在开发环境中创建方案并进行发现。


2

我的问题是SQL Server如何处理需要将更多数据量拉入缓冲区缓存的查询,然后有可用空间

为了回答这一特定部分,让我告诉您如何进行管理。页面大小为8KB。当您运行查询以请求大数据集并且需要将大量页面带入内存时,SQL Server 不会一次完成所有页面。它将找到特定的页面,并将一个8KB的页面逐个放入内存,从中读取数据并给出结果,现在假设这种情况继续存在,因为在这种情况下,内存不足的情况将被刷新到旧页面。像@Max指出的磁盘。如您所正确猜测的那样,内存不足可能会减慢速度,因为删除旧页面会花费一些时间。这是检查点和Lazywriter的地方变成图片。Lazywriter的工作是确保始终有一些可用内存,以将新页面带到磁盘上。当遇到较低的可用缓冲区时,将触发它并为新页创建可用空间。

编辑

我明白了,但是令我有些困惑的是,如果您要加入\ filtering数据,而这些结果超出了缓存的大小,将会发生什么。

甚至在查询运行之前就确定了用于联接和筛选的内存,并假设确实存在内存不足,并且运行操作所需的内存不可用,SQL Server处理器将授予“必需的内存”,即

所需的内存:运行排序和哈希联接所需的最小内存。之所以称为“必需”,是因为如果没有可用的内存,查询将不会启动。SQL Server使用此内存创建内部数据结构来处理排序和哈希联接。

因此,至少查询将开始运行,但是在运行时,中间结果很可能会溢出到Tempdb,从而使其变慢。我强烈建议您阅读理解查询内存授权


我明白了,但是令我有些困惑的是,如果您要加入\ filtering数据,而这些结果超出了缓存的大小,将会发生什么。需要编译数据以产生返回集,但是返回集大于缓存的大小。在产生最终结果之前,是否仍在内部循环页面通过缓存?我的想法是,由于它将超出缓存,然后将结果从磁盘读取,因此会将结果写入tempdb,但不知道是这种情况
Dustin

2
@Dustin编辑了我的答案,请检查
-Shanky
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.