本文涉及的内容均不是原创,是记录本身在学习IO、执行计划的过程当中学习其余大牛的博客和心得并记录下来,之因此想写下来是为了记录本身在追溯的过程遇到的几个问题,并把这些问题弄清楚。 本章最后已贴出原文地址。html
要理解逻辑读、物理读、预读这三个概念,先要搞懂SQL Server的数据存储方式。数据库
SQL Server数据库包括数据文件和日志文件,一个数据库能够有一个或多少数据文件、日志文件。全部的数据存储在数据文件中,数据文件能够划分为再小的单元,咱们称为“页”。每页大小8k。8个页面构成一个区。SQL Server对于页的读取是最原子性,要么读完一页,要么彻底不读。页之间的数据组织结构为B树。 因此SQL Server对于逻辑读、物理读、预读的单位都是页。缓存
2.1 初识三读性能
先来看个例子。示例数据库AdventureWorks。查询Sales.SalesOrderDetail学习
从截图中能够看出,这里读取多少次也就是读取了【多少页】数据。这个也是我一开始没搞懂的地方。优化
预读:在查询计划生成的过程当中,用估计的信息去硬盘读取数据到缓存中,预读1242页,也就是从硬盘中读取了1242页放到了缓存中。spa
物理读:查询计划生成好之后,若是缓存缺乏所须要的数据,再从硬盘里读取缺乏的数据到缓存里。.net
逻辑读:从缓存中读取数据。逻辑读1240次,也就是从缓存中读取1240页数据。日志
2.2 逻辑读、物理读、预读的关系htm
再次运行上面的语句得出如下结果
从图中能够看出,此次没有屋里读取和预读次数,只有逻辑读取次数,根据前面的概念咱们能够分析出:第二次查询能够直接从缓存中读取所须要的数据。 按照咱们的理论,貌似逻辑读取次数=物理读取次数+预读次数。但你会发现前面咱们1240并不等于1242+3.这又是为何呢?
一、首先要说明,逻辑读取次数并不绝对等于物理读取次数和预读次数之和。第二次查询物理读取次数和预读次数都是0。预读是按照估计的信息去读取信息,所以读取的页数并不必定准确,可能多于也可能少于实际的页数。
二、若是预读的页数包括了所有数据,那么就不会有物理读取次数。
三、有时候出现逻辑读取次数大于物理读取次数加上预读次数,这是由于在预读以前缓存中已经存在部分须要的数据。
当SQL Server执行一个查询时,SQL Server会开始第一步,生成执行计划。同时用估计的数据去硬盘读取数据(预读)。这两个第一步是并行的,SQL Server经过这种方式来提升查询性能。执行计划生成好之后去缓存读取数据。当发现缓存缺乏所须要的数据后让缓存再次去读硬盘(物理读)。而后从缓存中读取全部数据(逻辑读)。
估计的页数也能够从这个DMV中查询。若是第二次缓存后可以使用DBCC DROPCLEANBUFFERS清理缓存(生产慎用)。
SELECT page_count FROM sys.dm_db_index_physical_stats (DB_ID('AdventureWorks2008R2'),OBJECT_ID('Sales.SalesOrderDetail'),NULL,NULL,'sampled')
理解逻辑读、物理读、预读这三个概念主要是理解语句的查询过程以及那个步骤是去缓存数据、那个步骤又是去硬盘读取数据、那个步骤又是根据估计的信息去读取数据。从应用的角度来讲这三个数量并非绝对的数量加和关系,关键仍是要看理论语句的查询过程。在对语句进行优化时重点仍是逻辑读的次数,经过优化语句来检查逻辑读的次数来减小IO开销。
http://www.canway.net/Original/shujuku/012CE2016.html
http://www.cnblogs.com/CareySon/archive/2011/12/23/2299127.html
http://www.cnblogs.com/kissdodog/archive/2013/06/25/3155016.html