性能调优:理解Set Statistics IO输出
性能调优是DBA的重要工作之一。很多人会带着各种性能上的问题来问我们。我们需要通过SQL Server知识来处理这些问题。经常被问到的一个问题是:早上这个存储过程运行时间还是可以的,但到了晚上就很慢很慢。对此,我们可以笑着回答:这个存储过程运行多次后,已经累趴了,所以很慢。
存储过程或语句运行时间取决于服务器的工作量。如果在晚上,服务器负担很重的话,你的存储过程可能需要更多的时间来运行,因为它在等待CPU周期(CPU cycle)和IO完成(IO completion)。为了获得一致的响应时间,我们需要减少执行完成的资源需求,那就是所谓的性能调优。
IO和CPU是完成执行的主要资源使用对象。更少的资源使用,更稳定的性能表现。这篇文章我们来理解下性能调优中DBCC STATISTCS IO所扮演的角色。
默认情况下SET STATISTCS IO是停用的,我们可以通过下列语句在当前会话级别打开。
SET STATISTICS IO ON
这个语句可以帮助我们获得在语句执行时,所发生IO数(页读/写)。我们来看一个例子的输出。
USE StatisticsDB
GO
SELECT * INTO SalesOrderDetail FROM AdventureWorks2008R2.Sales.SalesOrderDetail
GO
SET STATISTICS IO ON
DBCC dropcleanbuffers
DBCC freeproccache
GO
SELECT * FROM SalesOrderDetail
GO
SELECT * FROM SalesOrderDetail
Set Statistics IO的输出信息可以在消息TAB页里找到。同样的语句我们执行了2次,第一次是在清空缓存后执行,第2次没有。
我们来看下输出信息:
扫描计数(Scan count):
根据微软在线帮助,扫描计数是在任何方向都达到叶级别后启动的查询/扫描数,目的在于检索用于构造输出的最终数据集的所有值。
- 如果使用的索引是主键的唯一索引或聚集索引并且您仅查找一个值,则扫描计数为 0。 例如 WHERE Primary_Key_Column = <value>。
当您使用对非主键列定义的非唯一的聚集索引搜索一个值时,扫描计数为 1。 这是为了针对您正在搜索的键值检查重复值。 例如 WHERE Clustered_Index_Key_Column = <value>。
当 N 为通过使用索引键定位键值后,在叶级别的左侧或右侧启动的不同查找/扫描数时,则扫描计数为 N。
这个数字告诉我们优化器所选择的计划,对这个对象的重复读取次数。很多人误以为这个是对整张表的读取次数,这是完全错误的。
我们通过一个例子来理解扫描计数。
CREATE TABLE ScanCount (Id INT IDENTITY(1,1),Value CHAR(1))
INSERT INTO ScanCount (Value ) VALUES ('A') ,('B'),('C'),('D'), ('E') , ('F')
CREATE UNIQUE CLUSTERED INDEX ix_ScanCount ON ScanCount(Id) SET STATISTICS IO ON
--Unique clustered Index used to search single value
SELECT * FROM ScanCount WHERE Id =1
--Unique clustered Index used to search multiple value
SELECT * FROM ScanCount WHERE Id IN(1,2,3,4,5,6)
--Unique clustered Index used to search multiple value
SELECT * FROM ScanCount WHERE Id BETWEEN 1 AND 6
我们来看下上面3个查询语句的输出。
在第1个SELECT语句的输出里,扫描计数为0。这和MSDN里在线帮助“如果使用的索引是主键的唯一索引或聚集索引并且您仅查找一个值,则扫描计数为 0。”描述一致。因为它是唯一索引(聚集/非聚集索引),不需要在叶子层,进行进一步的向左或向右扫描,因为这里只有一个值来匹配。那也是在唯一索引上查找单一值,扫描计数为0的原因。扫描计数是1的话,会在非唯一索引(聚集或非聚集索引)上发生。
对于第2个SELECT语句,扫描计数是6.这是因为我们在找多个不同值。MSDN在线帮助对此有详细说明: “如果使用的索引是主键的唯一索引或非聚集索引,你在查找N个值,则扫描计数为N。”。
我们来看看执行计划里的SEEK谓语,将更清晰:
即使只有一个where条件,还是会分裂成多个谓语。对于每个SEEK谓语,它会生成1个扫描数。
对于最后一个SELECT语句,扫描计数为1,因为MSDN在线帮助说了: “当 N 为通过使用索引键定位键值后,在叶级别的左侧或右侧启动的不同查找/扫描数时,则扫描计数为 N。” 在叶子节点聚集索引结构用来找到1值后,叶子层的向左扫描开始,直到找到值6。我们看下执行计划里的SEEK 谓语,将更清晰:
逻辑读取(logical Read):
从数据缓存读取的页数。数字越小,性能越好。在性能调优中这个数字非常重要。因为它不会随着执行又执行而改变,除非数据或查询语句有变动。在进行性能调优时,这个可以作为性能提升的重要参考。
物理读取(physical reads):
从磁盘读取的页数。这个会随着执行又执行而改变。大多数情况下,连续第2次的执行时,它的物理读取值为0(可以参考上面连续查询的物理读取数变化)。
如果连续执行后,物理读取次数下降了,我们可以假定是服务器上内存使用配置的错误,或者服务器工作量饱和,有内存压力。你需要在服务器级别思考问题的原因。在查询调优时,这个数字不太重要,因为它一直在变,对于下降这个值,你不能对它做出太多控制。
预读 (read-ahead reads):
为进行查询而放入缓存的页数。这个值告诉我们物理页读取数,即SQL Server执行的,作为预读机制的一部分。在查询执行请求那些可能用到页之前,SQL Server把物理数据页读入缓存,用于完成接下来查询的页需要。
可以看到,物理读取是2次,预读是946次。这就是说,查询执行请求了2个页,并预读了946个页到数据缓存,SQL Server估计下次查询可能要用到这些页。和物理读取一样,这个值对在查询调优里并不重要。
lob 逻辑读取(lob logical reads):
从数据缓存读取的 text、ntext、image 或大值类型 (varchar(max)、nvarchar(max)、varbinary(max)) 页的数目。这个和逻辑读一样重要,我们要非常重视。
lob 物理读取(lob physical reads):
从磁盘读取的 text、ntext、image 或大值类型页的数目。
lob 预读(lob read-ahead reads):
为进行查询而放入缓存的 text、ntext、image 或大值类型页的数目。
总结下,逻辑读取和LOB逻辑读取是2个重要数值,在性能调优时,我们要重点围观。如果把这2个值调低,不在本文的讨论范围。通常创建合适的索引或重写查询可以帮助我们彻底降低这2个值。
参考文章:
性能调优:理解Set Statistics IO输出的更多相关文章
- 性能调优之访问日志IO性能优化
性能调优之访问日志IO性能优化 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:908821 ...
- 性能调优3:硬盘IO性能
数据库系统严重依赖服务器的资源:CPU,内存和硬盘IO,通常情况下,内存是数据的读写性能最高的存储介质,但是,内存的价格昂贵,这使得系统能够配置的内存容量受到限制,不能大规模用于数据存储:并且内存是易 ...
- 性能调优:理解Set Statistics Time输出
在性能调优:理解Set Statistics IO输出我们讨论了Set Statistics IO,还有如何帮助我们进行性能调优.这篇文章会讨论下Set Statistics Time,它会告诉我们执 ...
- JVM | 第1部分:自动内存管理与性能调优《深入理解 Java 虚拟机》
目录 前言 1. 自动内存管理 1.1 JVM运行时数据区 1.2 Java 内存结构 1.3 HotSpot 虚拟机创建对象 1.4 HotSpot 虚拟机的对象内存布局 1.5 访问对象 2. 垃 ...
- mysql监控、性能调优及三范式理解
原文:mysql监控.性能调优及三范式理解 1监控 工具:sp on mysql sp系列可监控各种数据库 2调优 2.1 DB层操作与调优 2.1.1.开启慢查询 在My.cnf文件中添加如 ...
- [转]SQL Server 性能调优(io)
目录 诊断磁盘io问题 常见的磁盘问题 容量替代了性能 负载隔离配置有问题 分区对齐配置有问题 总结 关于io这一块,前面的东西如磁盘大小,磁盘带宽,随机读取写入,顺序读取写入,raid选择,DA ...
- 在SQL Server 2016里使用查询存储进行性能调优
作为一个DBA,排除SQL Server问题是我们的职责之一,每个月都有很多人给我们带来各种不能解释却要解决的性能问题. 我就多次听到,以前的SQL Server的性能问题都还好且在正常范围内,但现在 ...
- JVM性能调优监控命令jps、jinfo、jstat、jmap+jhat、jstack使用详解
JDK本身提供了很多方便的JVM性能调优监控工具,除了集成式的VisualVM和jConsole外,还有jps.jinfo.jstat.jmap+jhat.jstack等小巧的工具,本博客希望能起抛砖 ...
- [大牛翻译系列]Hadoop(16)MapReduce 性能调优:优化数据序列化
6.4.6 优化数据序列化 如何存储和传输数据对性能有很大的影响.在这部分将介绍数据序列化的最佳实践,从Hadoop中榨出最大的性能. 压缩压缩是Hadoop优化的重要部分.通过压缩可以减少作业输出数 ...
随机推荐
- springrain 1.1 发布,spring 的极简封装
经过2个月的测试修改,springrain1.1已经稳定,今日发布. 主要改动如下: 1.添加批量更新和保存的方法 2.添加maven分支 3.添加博客管理的demo 4.增加redis做为缓存实现 ...
- 分享我开发的网络电话Android手机APP正式版,图文详解及下载
分享我开发的网络电话Android手机APP正式版,图文详解及下载 分享我开发的网络电话Android手机APP正式版 实时语音通讯,可广域网实时通讯,音质清晰流畅! 安装之后的运行效果: 第一次安装 ...
- log4net入门
简介 几乎所有的大型应用都会有自己的用于跟踪调试的API.因为一旦程序被部署以后,就不太可能再利用专门的调试工具了.然而一个管理员可能需要有一套强大的日志系统来诊断和修复配置上的问题. 经验表明,日志 ...
- Oracle常用函数笔记
一.字符函数 1.dual 临时表 oracle中的临时变量表,此表只返回第一行第一列 例如:select sysdate from dual 输出:2014-6-9 11:20:39 2.Initc ...
- select * from table 时间长
优化中发现一个存储过程执行20秒通过profiler 抓取发现时间主要消耗在一个select * from 表,那么问题来了select几万数据竟然花了将近20秒? 问题排查清了程序前端使用了data ...
- STC12C5A60S2笔记6(中断)
1. 基本特性 1) 中断源 STC12C5A60S2共有十个中断源,每个中断源可设置4类优先级:当相同优先级下各中断优先级由高到低依次如下: 1.1)INT0(外部中断0) 中断向量地址 0003H ...
- Java多线程8:wait()和notify()/notifyAll()
轮询 线程本身是操作系统中独立的个体,但是线程与线程之间不是独立的个体,因为它们彼此之间要相互通信和协作. 想像一个场景,A线程做int型变量i的累加操作,B线程等待i到了10000就打印出i,怎么处 ...
- Aoite 系列(03) - 一起来 Redis 吧!
Aoite 是一个适于任何 .Net Framework 4.0+ 项目的快速开发整体解决方案.Aoite.Data 适用于市面上大多数的数据库提供程序,通过统一封装,可以在日常开发中简单便捷的操作数 ...
- JavaScript使用DeviceOne开发实战(四)仿优酷视频应用
开发之前需要考虑系统的差异性,比如ios手机没有回退键,所以在开发时一定要考虑二级界面需要有回退键,否则ios的手机就会陷入到这个页面出不去了.安卓系统有回退键,针对这个情况需要要求用户在3秒钟之内连 ...
- 系统空闲时间判断&命名验证
一.系统空闲时间判断 需要一个自动登录注销的功能,当鼠标移动和或者键盘输入的时候认为当前用户在线,否则过了设置时间就自动退出.好在前辈们留下了这样的一个类: MouseKeyBoardOperate: ...