数据库系统严重依赖服务器的资源:CPU,内存和硬盘IO,通常情况下,内存是数据的读写性能最高的存储介质,但是,内存的价格昂贵,这使得系统能够配置的内存容量受到限制,不能大规模用于数据存储;并且内存是易失性的,不能持久化存储数据,这使得内存只能作为运行时的高速缓存,而硬盘是永久存储数据的理想介质,价格低廉,在系统停电时,能够保持数据不丢失。但是,硬盘是低速的存储介质,输入和输出(IO)速度比内存低很多。因此,在实际运行的数据库系统中,相对于内存而言,硬盘的IO有更大可能性成为系统性能的瓶颈。

内存和硬盘都是存储资源和IO资源,木桶原理适用于SQL Server内部的资源争用,资源的短板就是系统的瓶颈。由于内存的容量相对较小,IO速度快,因此,内存更有可能成为争用的存储资源;而硬盘容量大,IO速度快,因此,硬盘更有可能成为系统争用IO资源。SQL Server为了平衡存储和IO资源的争用,在把数据从硬盘读取到内存后,会把数据缓存到内存中,当重复访问数据时,不需要从硬盘,而是直接从内存中获取。由于这个机制,为系统配置足够多的内存可以最小化硬盘IO,因为硬盘读取数据的速度远远低于内存,所以,尽可能减少硬盘IO可以在很大程度上提供系统的性能。

一,硬盘IO的延时

对于SQL Server数据库系统,限制查询响应的主要因素是硬盘的延时,根据硬盘的物理构造(磁道和扇区),延时可以分为寻道延时和旋转延时:

  • 寻道延时:硬盘的物理刺头移动并定位到所需数据的时间,
  • 旋转延时:硬盘旋转到所需数据的时间,通常用MB/S,或IO吞吐量来衡量

在OLTP系统中,数据更新操作较多,每次读取的数据量少,目标数据的位置相对随机(随机读写),因此,对于寻道延时要求更高,硬盘需要花费更多的寻道时间。

在DSS/DW系统中,事务的运行时间更长,数据相对静态,不常更新,读操作比写操作的要求更高,顺序读操作占比很高,因此,IO吞吐量更重要,可以通过硬盘的盘面来增加顺序访问的IO吞吐量。

二,根据WaitType侦测IO性能

SQL Server引擎把IO作为一个资源来看待,在多任务的现代数据库系统中,同一时刻会接收到很多查询请求,每一个查询请求都需要申请系统资源(CPU、内存和IO),才能继续执行下去,然而系统的资源是有限的,当查询争用资源时,有些查询请求资源得到满足,顺利执行下去,有些查询请求的资源得不到满足,该查询就被阻塞,处于等待资源分配的状态。当出现IO性能问题时,查询语句会被硬盘IO阻塞,这使得执行计划被迫挂起(或阻塞)来等待资源,SQL Server通过DMV来显示系统运行的状态,用等待类型来表示不同的阻塞信息。

1,数据文件的IO

如果SQL Server 出现 IO 性能问题,那么在SQL Server 内部通过DMV sys.dm_exec_requests的wait_type,来反馈 IO 问题。如果查询请求的wait_type长时间处于PageIOLatch_XX,那么说明系统不能很快把数据读取到内存中。

PAGEIOLATCH_xx :用于描述数据页的IO争用,说明系统正在从硬盘加载数据到内存的Buffer Pool中

当SQL Server 要去读或写一个Page的时候,首先会在Buffer Pool里寻找,如果在Buffer Pool中找到了,那么读写操作会继续进行,没有任何等待。如果没有找到,那么SQL Server 就会设置Wait_Type为PageIOLatch_EX(写)或PageIOLatch_SH(读),然后发起一个异步IO操作,将页面读入Buffer Pool中,在IO没有完成之前,Request将会保持在PageIOLatch_EX(写)或PageIOLatch_SH(读)的等待状态。IO消耗的时间越长,等待的时间越长。

2,日志文件的写入

日志文件以写为主,工作量由修改命令激发的事务数量决定。当SQL Server要写事务到日志文件时,如果Disk 不能及时完成IO请求,那么事务就无法提交,SQL Server 不得不进入WriteLog 等待状态,直到事务被成功记录到日志文件中,才会提交当前的事务。

如果request经常出现WriteLog的Wait type,说明事务日志的写请求不能被Disk及时完成,这种情况,对SQL Server 整体性能影响较大。

WRITELOG:在数据被修改时,在Log Cache和Buffer Cache中都会有记录,如果在Log Cache中的数据在checkpoint时写入硬盘,就会发生这种等待。

LOGBUFFER等待:很少出现,当一个任务正在等待存储日志到Log Buffer中时,就会出现LOGBUFFER等待,出现这种等待,说明日志所在的硬盘无法响应请求。如果把日志文件放在一个非常慢的硬盘上,而数据文件放在一个非常快的硬盘上,就会出现这种等待。

3,AYSNC_IO_COMPLIETION和IO_COMPLIETION也是IO瓶颈的潜在指标

  • AYSNC_IO_COMPLIETION:标识任务正在等待IO请求来完成操作,当一个应用程序连接SQL Server,在处理数据时变得非常慢,很可能就会出现这种类型的等待。
  • IO_COMPLIETION:发生在一个任务正在等待用于非数据页IO的IO操作上,非数据页,一般是指日志文件,通常发生在修改大量修改,或者内存中存在大量的脏数据时。

三,影响读写性能的因素

数据库系统对IO的性能依赖较高,那么影响数据库系统读写性能的因素有哪些呢?

1,物理硬盘的IO能力

机械硬盘的IO速度没有固态硬盘快,可以考虑把数据库系统的机械硬盘更新为固态硬盘。

2,内存对硬盘IO的影响

在SQL Server Engine 访问数据时,如果相应的data不存在于Buffer Pool,那么Buffer Manager 从Disk中的Data File(mdf 或 ndf)中将相应的data page读取到内存中。SQL Server 将data page缓存起来。理想情况下,只要SQL Server能够使用的内存充足,SQL Server 会将所有读取到内存的中Data Page缓存到Buffer Pool中。对于读取操作,只要相应的数据都缓存在内存中,Select 就不会有任何硬盘IO。

当Buffer Pool空间不足时,SQL Server 激活 LazyWriter,主动将内存中一些很久没有使用的Data Cache和 Plan Cache 清除,mark为Free buffer,供其它Data Page使用。如果这些Page上的修改还没有被CheckPoint写回Disk,那么LazyWrite会将其写回。

3,碎片和压缩

如果数据页面或index 页面的碎片很多,每个页面存储的数据行较少,那么SQL Server 需要读写更多的Page。如果数据在页面里存储的非常紧凑,存储相同数据所消耗的Page越少,并且可以充分利用SQL Server 预读的优势,减少IO。

压缩技术不仅使数据占用的Disk 空间减少,而且能够减少IO。由于数据在写入Disk之间经过压缩处理,存储相同数据所消耗的Page减少,读取的Data Page会减少。压缩技术在一定程度上能够降低IO,但需要付出一定的代价:额外消耗少量的CPU和内存来解压缩。

4,利用多个物理硬盘实现Data File的并发读写

在DB中的FileGroup 创建多个File,将这些File存放到不同的Physical Disk上。File 分布到不同的Physical Disk上,IO也会分布到不同的Physical Disk上,这样能够实现数据的并发读取,提高读取性能。

对于日志文件,SQL Server会频繁的写事务日志。只要数据库发生修改,就会不断地写入日志文件。如果不能及时完成日志文件的IO,会导致事务的延迟提交,对性能的影响较大,所以,尽量将日志文件放到写入速度快的Disk上。SQL Server 顺序写事务日志,在一个时间点,SQL Server 只会写一个日志文件。在不同的Physical Disk上创建多个log file对性能基本没有帮助。

5,工作负载

日志文件以写为主,工作量由修改命令申请的事务数量决定,日志文件是顺序写的,写入速度快于随机写。如果日志记录不能及时写入,那么Request会处于WriteLog等待状态,对系统整体性能影响较大。

数据文件写入的数据量由修改量决定,SQL Server除了设置bulk logged 恢复模式之外,没有太大的调整选项。

数据文件读取的数据量,由访问的数据量和Buffer Pool中缓存的数据量共同决定。如果访问的数据量减少或者内存缓存区增加,都可以降低SQL Server 从Physical Disk读取的Data Page数量。在内存不变的情况下,可以通过优化查询语句,减少数据访问量,来提高SQL Server 数据文件的读取性能。

四,硬盘IO的性能优化

硬盘IO的性能调优,通常来说,跟Buffer Pool的大小和数据的分布有关

1, Buffer Pool

Buffer Pool是SQL Server数据库系统的缓冲池,用于缓存从硬盘读取的数据页。当SQL Server所需的数据不在内存的Buffer Pool中时,就会触发硬盘IO,把数据从硬盘中的文件中读取到内存中的Buffer Pool中。如果所需的数据存在于Buffer Pool中,SQL Server直接从内存中获取数据,不会触发任何硬盘的IO操作。因此,内存容量足够大,硬盘IO将会足够小。如果系统存在内存压力,那么SQL Server将会频繁地触发硬盘IO,从硬盘文件中获取数据,这将会增加查询的响应时间。

2, 多硬盘并发IO

在存储数据时,把数据分布在不同的物理硬盘上,在读写数据时,可以把工作负载分担到不同的物理硬盘上,多个硬盘并发处理数据,将会大大降低数据的读写时间。

因此,在设计数据库系统时,应该尽量把数据分布到不同的物理硬盘上,并且每个硬盘上的数据量保持均衡,这样,才能最大化利用多硬盘的优势,实现数据的读写时间最小化。

3,日志文件

当修改数据时,事务会被记录到日志文件中,事务日志的写入速度,直接影响了数据更新查询语句的执行效率。当数据库中存在大量的修改操作时,应该把日志文件存储到IO性能最优的硬盘上,以减少日志文件写入的时间延迟。

4,tempdb数据库文件

tempdb是数据库实例中最繁忙的数据库了,在查询语句执行的过程中,查询语句创建的各种临时表,系统创建的中间表都位于tempdb中,tempdb的数据文件和日志文件的读写性能,直接影响了查询语句的执行时间,应该把tempdb数据库的数据文件部分到不同的物理硬盘中,并且把tempdb的日志文件存放到IO性能最优的硬盘上去。

简而言之,对于数据库系统的优化配置是:

  • 在OLTP系统中,合理的配置是把数据文件,日志文件和tempdb的文件分别存放到不同的物理硬盘上,从而分摊硬盘的IO争用。
  • 在OLAP系统中,事务运行时间长,规模大,数据相对静态,每次返回的数据量较大,对IO吞吐量的要求较高,因此,尽可能分摊硬盘的IO争用。

5,创建合适的索引

如果一个查询需要进行表扫描,一般是因为缺失合适的索引或索引统计信息过时,过多的扫描操作会引起内存不足,使得缓存中的数据或执行计划被清除(或者被转移到硬盘),然后从硬盘加载数据到内存。理想情况下,常用的数据应该尽可能久地驻留在内存中,避免不必要的内存活动。

创建合适的索引,并保证统计信息及时更新,能够避免不必要的表扫描,只加载小的数据集,能够减少IO操作的次数,优化IO性能。

6,数据压缩

数据压缩会使得相同的存储空间能够存储更多的数据量,一次IO操作能够加载更多的数据,这也能减少IO操作的次数,优化IO性能。

五,IO统计

IO请求的等待和挂起,数据库引擎记录对数据文件和日志文件的IO操作,缓存到函数:sys.dm_io_virtual_file_stats,对于数据文件,数据的物理读操作更为重要;对于日志文件,数据的读写操作都重要:

  • io_stall_read_ms:等待读操作的时间
  • io_stall_write_ms:等待写操作的时间

如果硬盘繁忙,数据库引擎发送的IO请求,可能会被IO子系统挂起(pending),数据库引擎把pending的IO请求缓存到视图:sys.dm_io_pending_io_requests,

  • io_pending:指定是否有IO请求挂起或完成

1,查看数据库文件的IO和等待IO完成的时间

select db_name(vfs.database_id) as db_name,
--vfs.file_id,
mf.name as file_name,
mf.type_desc as file_type,
vfs.sample_ms/1000/60/60 as sample_h,
vfs.io_stall_read_ms/vfs.num_of_reads as avg_stall_read_ms,
vfs.io_stall_write_ms/vfs.num_of_writes as avg_stall_write_ms, vfs.num_of_reads as physical_reads,
vfs.num_of_bytes_read/vfs.num_of_reads/1024 as avg_read_kb,
vfs.num_of_writes as physical_writes,
vfs.num_of_bytes_written/vfs.num_of_writes/1024 as avg_written_kb,
cast(vfs.size_on_disk_bytes/1024/1024/1024.0 as decimal(10,2)) as disk_size_gb,
--cast(mf.size/1024*8/1024.0 as decimal(10,2)) as file_size_gb,
vfs.file_handle
from sys.master_files mf
cross apply sys.dm_io_virtual_file_stats(mf.database_id,mf.file_id) as vfs
where mf.database_id=db_id() --current db
order by avg_stall_read_ms desc ,avg_stall_write_ms desc

2,查看pending的IO请求

select db_name(vfs.database_id) as db_name,
--vfs.file_id,
mf.name as file_name,
pr.io_type,
sum(pr.io_pending_ms_ticks) as io_pending_ms,
pr.io_pending
from sys.dm_io_virtual_file_stats(null,null) vfs
inner join sys.dm_io_pending_io_requests as pr
on vfs.file_handle=pr.io_handle
inner join sys.master_files mf
on vfs.database_id=mf.database_id
and vfs.file_id=mf.file_id
group by vfs.database_id,
mf.file_id,
mf.name,
pr.io_type,
pr.io_pending
order by vfs.database_id,
mf.name

3,计划缓存中的逻辑写排名

select
p.name as sp_name
,s.total_logical_reads
,s.total_logical_writes
,s.total_physical_reads
,s.total_elapsed_time
,s.total_worker_time
,s.cached_time
,s.execution_count
,s.type
,s.type_desc
from sys.procedures p
inner join sys.dm_exec_procedure_stats s
on p.object_id=s.object_id
where s.database_id=DB_ID()
and s.total_logical_writes>0
order by s.total_logical_writes

参考文档:

Windows Performance Monitor Disk Counters Explained

High Avg Disk Queue Length and finding the Cause

Disk Queue Length vs. Disk Latency Times: Which is Best for Measuring Database Performance

性能调优3:硬盘IO性能的更多相关文章

  1. [Spark性能调优] 第一章:性能调优的本质、Spark资源使用原理和调优要点分析

    本課主題 大数据性能调优的本质 Spark 性能调优要点分析 Spark 资源使用原理流程 Spark 资源调优最佳实战 Spark 更高性能的算子 引言 我们谈大数据性能调优,到底在谈什么,它的本质 ...

  2. spark 性能调优(一) 性能调优的本质、spark资源使用原理、调优要点分析

    转载:http://www.cnblogs.com/jcchoiling/p/6440709.html 一.大数据性能调优的本质 编程的时候发现一个惊人的规律,软件是不存在的!所有编程高手级别的人无论 ...

  3. JVM性能调优(4) —— 性能调优工具

    前序文章: JVM性能调优(1) -- JVM内存模型和类加载运行机制 JVM性能调优(2) -- 垃圾回收器和回收策略 JVM性能调优(3) -- 内存分配和垃圾回收调优 一.JDK工具 先来看看有 ...

  4. JVM性能调优2:JVM性能调优参数整理

    序号 参数名 说明 JDK 默认值 使用过 1 JVM执行模式 2 -client-server 设置该JVM运行与Client 或者Server Hotspot模式,这两种模式从本质上来说是在JVM ...

  5. MySql(九):MySQL性能调优——Schema设计的性能优化

    一.高效的模型设计 先了解下数据库设计的三大范式 第一范式:要求有主键,并且要求每一个字段原子性不可再分 第二范式:要求所有非主键字段完全依赖主键,不能产生部分依赖 第三范式:所有非主键字段和主键字段 ...

  6. linux性能调优概述

    - 什么是性能调优?(what) - 为什么需要性能调优?(why) - 什么时候需要性能调优?(when) - 什么地方需要性能调优?(where) - 什么人来进行性能调优?(who) - 怎么样 ...

  7. [转载]Java 应用性能调优实践

    Java 应用性能调优实践 Java 应用性能优化是一个老生常谈的话题,笔者根据个人经验,将 Java 性能优化分为 4 个层级:应用层.数据库层.框架层.JVM 层.通过介绍 Java 性能诊断工具 ...

  8. 性能调优的本质、Spark资源使用原理和调优要点分析

    本课主题 大数据性能调优的本质 Spark 性能调优要点分析 Spark 资源使用原理流程 Spark 资源调优最佳实战 Spark 更高性能的算子 引言 我们谈大数据性能调优,到底在谈什么,它的本质 ...

  9. hbase性能调优(1)

    hbase性能调优 标签: hbase 性能调优 | 发表时间:2014-05-17 15:10 | 作者:无尘道长 分享到: 出处:http://www.iteye.com 一.服务端调优 1.参数 ...

  10. 成为Java GC专家(5)—Java性能调优原则

    并不是每个程序都需要调优.如果一个程序性能表现和预期一样,你不必付出额外的精力去提高它的性能.然而,在程序调试完成之后,很难马上就满足它的性能需求,于是就有了调优这项工作.无论哪种编程语言,对应用程序 ...

随机推荐

  1. DOIS 2018 — OneAPM 蓝海讯通以数据为中心的 AIOps 平台亮相

    AIOps 近两年开始在运维圈子里面火了起来.一夜间传统和新兴的运维管理软件供应商,IT 运维系统开发商,大数据厂商,人工智能算法提供商,还有 BAT,大家都在谈论这个话题.在短短的不到 1 年时间中 ...

  2. Spark Standalone 提交模式

    一.Client提交模式 提交命令: ./spark-submit --master spark://node1:7077 --class org.apache.spark.examples.Spar ...

  3. HashMap和Hashtable的同和不同(详细比较)

    一.综述 可以直接根据hashcode值判断两个对象是否相等吗?肯定是不可以的,因为不同的对象可能会生成相同的hashcode值.虽然不能根据hashcode值判断两个对象是否相等,但是可以直接根据h ...

  4. 便捷的方式在手机上查看Unity3D的Console Log(调试信息 日志)

    Logs Viewer 功能描述 Using this tool you can easily check your editor console logs inside the game itsel ...

  5. oracle USING 用法

    提问 using(xx)中可以接多个列吗? using(xx)中的列可以接表名或别名吗? 在使用using的语句中,select * 可以使用吗? 如果表有别名t,select t.* from ta ...

  6. Hadoop2.7.6_01_部署

    1. 主机规划 主机名称 外网IP 内网IP 操作系统 备注 安装软件 mini01 10.0.0.11 172.16.1.11 CentOS 7.4 ssh port:22 Hadoop [Name ...

  7. linux下的文件目录结构

    linux的文件系统是采用层级式的树状目录结构,在此结构中的最上层是根目录“/”,然后在此目录下再创建其他的目录 - root,存放root用户的相关文件 - home,存放普通用户的相关文件 - b ...

  8. 牛客 小a与星际探索 bfs

    链接:https://ac.nowcoder.com/acm/contest/317/C?&headNav=acm来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ ...

  9. 面试总结——JVM篇

    前言:该篇主要对Java虚拟机相关的题目进行介绍. JVM篇 基本上在面试的时候,都会或多或少的涉及JVM,主要看面试官的侧重点,笔者在面试过程中,是通过volatile问题,引导了JVM相关问题上的 ...

  10. Mysql 关键字的优先级 分组 多表联查

    查看模式 select @@global.sql_mode; 关键字的优先级 from 来自 where 条件 group by 分组 having 筛选 select 查询 distinct 去重 ...