Rau*_*DBA 2 sql-server database-internals sql-server-2012 buffer-pool
我试图理解read-ahead reading,但对我来说似乎有点复杂。我在网上搜索并得到以下信息:
从阅读页面(微软文档):
预读预期完成查询执行计划所需的数据和索引页,并在查询实际使用这些页之前将它们放入缓冲区缓存。
从对为什么在 SQL Server 中首次执行查询时“物理读取”少于“预读”和“逻辑读取”的回答?作者:huntharo 在 Stack Overflow 上:
物理读取 - 查询被阻塞,等待页面从磁盘读取到缓存中以供立即使用。
Read-Ahead Read - 页面在阻塞查询之前被读取,并像所有读取一样被读入缓存。当您扫描索引时,预读是可能的,在这种情况下,可以假定索引中的下一个叶页是需要的,并且可以在查询实际表示需要它们之前为它们启动读取。这允许磁盘在 db 引擎检查先前获取的页面的内容时忙碌。
也许有人可以使用他们自己的解释来澄清上述内容,因为我找不到预读的详细解释。
举个例子,看看statistics io信息:
Table 'TestLarge'. Scan count 1, logical reads 159185, physical reads 348, read-ahead reads 159209
Run Code Online (Sandbox Code Playgroud)
查询总是从内存中读取数据(逻辑读取)。您的示例查询扫描TestLarge表在其执行期间涉及 159,185 个 8KB 内存页。
在执行期间,SQL Server 会做两件事。
如果所需页面已在内存中,则记录逻辑读取。
如果所需的页面不在内存中,则会记录物理读取。
在扫描操作期间,SQL Server 每隔一段时间就会花一点时间管理预读:
想象有一本书。你只得到索引。这本书的其余部分在当地图书馆。图书馆规定整本书不能借阅,每次访问最多只能从图书馆取50页。
您的任务是按照索引(a 到 z)中引用页面的顺序在家中组装这本书。你不能离开家,但你有一个朋友可以代你去图书馆。
索引中的第一个条目是“土豚”,它出现在本书的第 392 页。
你意识到一次一页地完成这项任务会非常低效,所以你不是把你的朋友送到图书馆看第 392 页,而是按索引顺序阅读 50 个条目,然后把要带到图书馆的页面列表交给你的朋友图书馆。此时您计算了 50 次预读。
现在你又回到处理“土豚”了。你面前没有第 392 页,所以你必须等待,什么都不做,直到你的朋友回来。这是物理读取。
当您的朋友到达时,您在处理第 392 页时计算逻辑读取。
您可以从您朋友带回的其他 49 页开始(计算每页的逻辑读取次数),但是您意识到,如果您在忙于从图书馆获取的页面列表时给您的朋友另一个列表,效率会更高在你面前工作。
每次您将要获取的页面列表发送给您的朋友到图书馆时,您都会计算预读次数。每次处理您面前的页面时,您都会计算一次逻辑读取。如果你发现自己没有你需要的下一页(因为你的朋友太慢了),你算一个物理阅读。
当您和您的朋友可以有效地重叠您的活动时,整体任务会更快完成。他们可能忙于获取您很快需要的页面,而您则忙于处理您面前的页面。如果这运行良好,您就不必等待您需要的下一页,尽管您确实会花一点时间告诉您的朋友该做什么。