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数据库备份的几个建议
- sqlserver中有几种锁定模式(SQL Server 开窗函数 Over代替游标的使用详解)
- sql server中check约束
- sql server提供的聚合函数(SQLServer行列互转实现思路聚合函数)
- SQL Server中找出执行时间过长的作业
- 阿里云sql server 2012(远程连接阿里云SqlServer 2012 数据库服务器的图文教程)
- sql server 管理日志可以删除吗(SQL Server查看login所授予的具体权限问题)
- sqlserver安装与使用教程(SQL Server 2017 Developer的下载、安装、配置及SSMS的下载安装配置图文教程详解)
- 将SQL Server数据迁移到MySQL的方法
- SQL SERVER存储过程中使用事务与try catch
- sqlserver判断null(SQL Server索引超出了数组界限的解决方案)
- SQL SERVER获取指定数据库中所有存储过程的参数
- sqlserver触发器修改当前字段(利用SQL Server触发器实现表的历史修改痕迹记录)
- sql server中通过datename获取日期中部分数据
- sql server显示当前登录用户命令(SQL Server正确删除Windows认证用户的方法)
- sql查询语句casewhen是什么意思(SQL Server中使用判断语句IF ELSE/CASE WHEN 案例)
- 终于来了,淘宝更改账户名测试中,快去看看你能不能修改(淘宝更改账户名测试中)
- 淘宝支持账号名修改,网友 终于可以 重新做人 了(淘宝支持账号名修改)
- 盘点那些年让人称奇的年终奖 最后一个赢辣条毫无悬念(盘点那些年让人称奇的年终奖)
- 你还没有升职吗 他竟因为几套激励理论,升职了(你还没有升职吗)
- 某知名企业绩效管理体系及薪酬分配体系操作手册(某知名企业绩效管理体系及薪酬分配体系操作手册)
- 职场人改不掉这4个习惯,只会越混越穷,一辈子也翻不了身(职场人改不掉这4个习惯)
热门推荐
- php商城支付接口(php实现银联商务公众号+服务窗支付的示例代码)
- mysql数据库触发器(MySQL中使用游标触发器的方法)
- nginx服务器有什么用(Nginx的作用详解,为什么在Web服务器中Nginx的比例越来越高?)
- mysql密码设置(mysql密码中有特殊字符&在命令行下登录的操作)
- wxpython 弹出对话框显示图片(WxPython建立批量录入框窗口)
- php redis应用场景(PHP商品秒杀问题解决方案实例详解mysql与redis)
- laravel关闭错误提示(解决laravel session失效的问题)
- mysql中如何进行模糊查询(MySQL模糊查询用法大全正则、通配符、内置函数)
- vue图片组件使用方法(Vue图片裁剪组件实例代码)
- 用docker搭建redis集群(docker实现redis集群搭建的方法步骤)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9