sql server中的逻辑读、物理读和预读
sql server中的逻辑读、物理读和预读
sql server中的逻辑读、物理读和预读在使用SET STATISTICS IO ON语句统计I/O时候,我们会看到类似下面的结果:
扫描计数 1,逻辑读取 2 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
那么它们代表什么呢?
预读:用于估计信息,去硬盘读取数据到缓存。
物理读:查询计划生成好以后,如果缓存缺少所需要的数据,让缓存再次去读硬盘。如果内存里没有缓存数据或执行计划(sql语句改变执行计划不能重用,需要重新计算执行计划),那么SQLSERVER就要去硬盘读取这些数据,这时候就是物理读,硬盘速度跟内存速度不在一个数量级别,所以物理读是比较慢的。
逻辑读:SQLSERVER去内存里面的缓存取数据或执行计划(执行计划可以重用),所以逻辑读是比较快的。
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 次。
上表的大小是17.406M。
每一页存储的数据是:8K=8192字节-96字节(页头)-36字节(行偏移)= 8060字节。
17.406*1024*1024 / 8060 ≈ 2 264
另外表中还有一些非数据占用的空间,因此上式的结果约等于逻辑读次数。
基本上,逻辑读、物理读、预读都等于是扫描了多少个页。
SQL Server的查询从理解各种读的步骤来看,可以理解为以下图:
通过上图来讲解各种读:
当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 次。
为什么这次全部都是逻辑读呢。因为刚才读过一次,数据全部都已经在缓存当中了,只需要从缓存中读就可以了,不需要再读取硬盘。
- sql server查询语句语法(详解SQL Server的简单查询语句)
- sqlserver拒绝访问怎么办(SQL server服务显示远程过程调用失败的解决方法)
- sqlserver 怎么建立触发器(SQL Server:触发器实例详解)
- sql server数据库权限(SQL Server中通用数据库角色权限的处理详解)
- sqlservercount函数怎么用(Sql Server中Substring函数的用法实例解析)
- sqlserver触发器修改当前字段(利用SQL Server触发器实现表的历史修改痕迹记录)
- sql server证书配置(SQL Server Alwayson创建代理作业的注意事项详解)
- sql server中实现split功能
- sql server 2014配置文件路径(SQL Server 2012 FileTable 新特性详解)
- sql server 锁超时(详解SQL Server中的事务与锁问题)
- sqlserver字符串截取填充(SQL Server实现split函数分割字符串功能及用法示例)
- Sql Server中的Null值
- sqlserver中根据日期时间获取秒数(sql server编写通用脚本实现获取一年前日期的方法)
- sql server 2008自定义函数(SQL SERVER 2012新增函数之逻辑函数CHOOSE详解)
- Sql Server事件探查器的作用
- sql server支持两种登录验证方式(远程登陆SQL Server 2014数据库的方法)
- 是不是快乐全被你拿走了(而是你得到的)
- 世界上只有妈妈好(世界上只有妈妈好的歌词)
- 为什么现在社会越来越卷了(现在社会为什么发展那么快呢)
- 直播带货能赚到很多钱吗(直播带货能赚到很多钱吗现在)
- 做网红真的很能赚钱吗(做网红真的很能赚钱吗)
- 10句英语常用(英语常用900句)
热门推荐
- 如何安全实现“记住我”的功能
- python爬虫入门自学(自学python爬虫的建议和周期预算)
- css导航栏特效(CSS导航栏及弹窗示例代码)
- pythonselenium怎么设置元素(Python2 Selenium元素定位的实现8种)
- vue element admin接口(Vue-Element-Admin集成自己的接口实现登录跳转)
- 详解从vue的组件传值着手观察者模式(详解从vue的组件传值着手观察者模式)
- python如何将运行结果存入txt中(详解python读取和输出到txt)
- vue在html里面怎么展示图片(v-html渲染组件问题)
- CSS3 transition过渡效果
- python元组汇总(Python数据类型之Tuple元组实例详解)