页面将根据需要读入内存,如果没有可用的可用内存,则最早的未修改页面将替换为传入页面。
这意味着,如果执行的查询所需要的数据量超出了内存容量,那么许多页面的内存寿命将非常短,从而导致大量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如何处理超出内存容量的更多数据的本质。