SQL Server数据存储的形式

  1.   预读:用估计信息,去硬盘读取数据到缓存。预读100次,也就是估计将要从硬盘中读取了100页数据到缓存。
  2.   物理读:查询计划生成好以后,如果缓存缺少所需要的数据,让缓存再次去读硬盘。物理读10页,从硬盘中读取10页数据到缓存。
  3.   逻辑读:从缓存中取出所有数据。逻辑读100次,也就是从缓存里取到100页数据。

  SQL Server存储的最小单位是页,每一页大小为8K,SQL Server对于页的读取是原子性的,要么读完一页,要么完全不读。即使是仅仅要获得一条数据,也要读完一页。而页之间的数据组织结构为B树结构。所以SQL Server对于逻辑读、预读、物理读的单位是页。

  先来看一个查询:

  DBCC DROPCLEANBUFFERS    --清空缓存
  SET STATISTICS IO ON --开启IO统计
  SELECT * FROM Person --查询语句

  显示消息如下:

(147517 行受影响)
表 'Person'。扫描计数 1,逻辑读取 2237 次,物理读取 6 次,预读 2226 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。 (1 行受影响)

  

  上表的大小是17.406M。

  每一页存储的数据是:8K=8192字节-96字节(页头)-36字节(行偏移)= 8060字节。

  17.406*1024*1024 / 8060 ≈ 2 264

  另外表中还有一些非数据占用的空间,因此上式的结果约等于逻辑读次数。

  基本上,逻辑读、物理读、预读都等于是扫描了多少个页。

从执行顺序上理解各种读

  SQL Server的查询从理解各种读的步骤来看,可以理解为以下图:

  (图是CareySon大哥的)

  通过上图来讲解各种读:

  当SQL Server执行一个查询语句时,SQL Serer会开始第一步,生成查询计划,同时用估计的数据去磁盘读取数据(预读),这两个第一步是并行的。SQL Server通过这种方式来提高查询性能。

  查询计划生成好了以后去缓存读取数据,当发现缓存缺少所需要的数据后让缓存再次去读硬盘(物理读)然后从缓存中取出所有数据(逻辑读)

  估计的页数可以通过DMV看到

  SELECT
  page_count
  FROM sys.dm_db_index_physical_stats
  (DB_ID('TestDataCenter'),OBJECT_ID('Person'),NULL,NULL,'sampled')

  显示结果如下:

  

  SQL Server就是根据这个东西进行预读。

  如果此时我们再执行上面的查询语句:

  SELECT * FROM Person    --查询语句

  看到消息如下:

(147517 行受影响)
表 'Person'。扫描计数 1,逻辑读取 2237 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。 (1 行受影响)

  为什么这次全部都是逻辑读呢。因为刚才读过一次,数据全部都已经在缓存当中了,只需要从缓存中读就可以了,不需要再读取硬盘。

  本文学习自:http://www.cnblogs.com/CareySon/archive/2011/12/23/2299127.html

SQL Server逻辑读、预读和物理读的更多相关文章

  1. 初谈SQL Server逻辑读、物理读、预读

    前言 本文涉及的内容均不是原创,是记录自己在学习IO.执行计划的过程中学习其他大牛的博客和心得并记录下来,之所以想写下来是为了记录自己在追溯的过程遇到的几个问题,并把这些问题弄清楚. 本章最后已贴出原 ...

  2. 初谈SQL Server逻辑读、物理读、预读【转】

    前言 本文涉及的内容均不是原创,是记录自己在学习IO.执行计划的过程中学习其他大牛的博客和心得并记录下来,之所以想写下来是为了记录自己在追溯的过程遇到的几个问题,并把这些问题弄清楚. 本章最后已贴出原 ...

  3. SQL SERVER 2005修改数据库名称,包括物理文件名和逻辑名称

    SQL SERVER 2005修改数据库名称,包括物理文件名和逻辑名称   原来数据库名称为 aa,物理文件名称为 aa.mdf 和 aa_log.ldf:   需要修改数据库名称为 bb,物理文件名 ...

  4. SQL Server索引进阶:第九级,读懂执行计划

    原文地址: Stairway to SQL Server Indexes: Level 9,Reading Query Plans 本文是SQL Server索引进阶系列(Stairway to SQ ...

  5. 理解SQL SERVER中的逻辑读,预读和物理读

    转自:https://www.cnblogs.com/CareySon/archive/2011/12/23/2299127.html 在我的上一篇关于SQL SERVER索引的博文,有圆友问道关于逻 ...

  6. SQL Server中STATISTICS IO物理读和逻辑读的误区

    SQL Server中STATISTICS IO物理读和逻辑读的误区 大家知道,SQL Server中可以利用下面命令查看某个语句读写IO的情况 SET STATISTICS IO ON 那么这个命令 ...

  7. sqlserver性能调优中的逻辑读,物理读,预读是什么意思

    表 'T_EPZ_INOUT_ENTRY_DETAIL'.扫描计数 1,逻辑读 4825 次,物理读 6 次,预读 19672 次.SQL SERVER 数据库引擎当遇到一个查询语句时,SQL SER ...

  8. SQL Server 中的事务与事务隔离级别以及如何理解脏读, 未提交读,不可重复读和幻读产生的过程和原因

    原本打算写有关 SSIS Package 中的事务控制过程的,但是发现很多基本的概念还是需要有 SQL Server 事务和事务的隔离级别做基础铺垫.所以花了点时间,把 SQL Server 数据库中 ...

  9. SQL Server中的事务与其隔离级别之脏读, 未提交读,不可重复读和幻读

    原本打算写有关 SSIS Package 中的事务控制过程的,但是发现很多基本的概念还是需要有 SQL Server 事务和事务的隔离级别做基础铺垫.所以花了点时间,把 SQL Server 数据库中 ...

随机推荐

  1. 大气漂亮的jQuery水晶样式下拉菜单

    预览地址:http://demo.zzblo.com/sc/2013/11/201311131041 下载地址:http://sc.zzblo.com/js/201311/79.html

  2. 用MOS管防止电源反接的原理

    电源反接,会给电路造成损坏,不过,电源反接是不可避免的.所以,我么就需要给电路中加入保护电路,达到即使接反电源,也不会损坏的目的. 一般可以使用在电源的正极串入一个二极管解决,不过,由于二极管有压降, ...

  3. mongoDB研究笔记:分片集群部署

    前面几篇文章的分析复制集解决了数据库的备份与自动故障转移,但是围绕数据库的业务中当前还有两个方面的问题变得越来越重要.一是海量数据如何存储?二是如何高效的读写海量数据?尽管复制集也可以实现读写分析,如 ...

  4. HTML5按钮的点击态问题

    开始在网页上实现点击态是mousedown mouseup来实现但是手机HTML5实现点击态怎么就不可以了呢 经过查资料才知道手机浏览器来实现点击态是通过 touchstart touchend实现

  5. 利用IIS应用请求转发ARR实现IIS和tomcat整合共用80端口

    现在网上流传的实现iis和tomcat共享80端口的方法是基于isapi_redirect插件实现的, 我的实现方法不同, 原理相似,具有更好的优点. 先说下基于isapi_redirect缺点,ja ...

  6. .NET转Java学习规则

    做一个个人Blog(博客) 过程分3个大阶段: 使用servlet/jsp和jdbc,mysql完成第一阶段Blog 项目修改为Spring(IOC+MVC)+SpringJdbc+MyBatis模式 ...

  7. 用JQ仿造礼德财富网的图片查看器

    现在就职于一家P2P平台,自然也会关注同行其它网站的前端技术,今天要仿造的是礼德内页的一个图片查看器效果.不过说白了,无论人人贷也好礼德财富也好,很多地方的前端都做的不尽如人意,比如忽略细节.缺乏交互 ...

  8. Java设计模式4:单例模式

    前言 非常重要,单例模式是各个Java项目中必不可少的一种设计模式.本文的关注点将重点放在单例模式的写法以及每种写法的线程安全性上.所谓"线程安全性"的意思就是保证在创建单例对象的 ...

  9. Java多线程16:线程组

    线程组 可以把线程归属到某一个线程组中,线程组中可以有线程对象,也可以有线程组,组中还可以有线程,这样的组织结构有点类似于树的形式,如图所示: 线程组的作用是:可以批量管理线程或线程组对象,有效地对线 ...

  10. Java多线程2:Thread中的实例方法

    Thread类中的方法调用方式: 学习Thread类中的方法是学习多线程的第一步.在学习多线程之前特别提出一点,调用Thread中的方法的时候,在线程类中,有两种方式,一定要理解这两种方式的区别: 1 ...