背景
客户反馈最近一段时间数据库运行缓慢,磁盘的压力很大,现在有两种不同的分析结论,存储设备性能下降和数据库压力变大,请我们进行系统的分析,给一个结论
现象
登录SQL专家云,进入性能指标页面,选择客户反馈系统运行慢时间段,并选择I/O相关的性能指标。
Avg.Disk Write Queue Length和Avg.Disk Read Queue Length代表磁盘的写、读排队长度,Total代表所有磁盘的总和。通过图表看到,排队情况非常严重,尤其是读队列。和现实生活中的排队一样,队列越长,通过性越差,等待时间越长,正常值在10以下。
G盘为数据文件和日志文件的存放盘,单独看G盘的指标和Total的基本一致,说明压力全部来自于G盘。
%Idle Time代表磁盘的百分比空闲时间,值越小说明越繁忙。从图表中看到绝大多数时间都在10%以下,说明G盘非常繁忙。
Avg.Disk sec/Read和Avg.Disk sec/Write代表每个读、写操作的响应时间,单位是秒。从图表中看到绝大多数的响应时间在100毫秒左右,而且已经有一定比例的时间在1秒以上了,说明磁盘的响应已经很慢了。
Disk Read Bytes/sec和Disk Write Bytes/sec代表每秒钟读、写的字节数。从图表中看到,每秒读取500M左右,每秒写入30M左右,读取的量非常大,这和读队列长度的指标非常高是吻合的。
Page Life Expectancy代表数据页在缓冲区(内存)内停留的时间,从图表中看到,数值在10左右,非常低, 说明内存压力非常大。Lazy writes/sec代表每秒钟将缓冲区中更新过的数据写入到数据文件中并从缓冲区中移除的次数。从图表中看到,大多数时间都在500左右,同样证明内存压力非常大。
分析
通过以上五组数据,很容易得出结论,磁盘比较缓慢是因为读取压力非常大(500M/s)导致的,在这么大的压力下,磁盘还能有这种响应时间已经是性能非常好了,从而排除存储设备性能下降的可能。
SQL Server查询数据都是在缓冲区(内存)内完成的,当数据不在缓冲区内,就要从数据文件中读取到缓冲区内。新数据进入缓冲区时,如果缓冲区空间不足,就得清除其他的数据,Page Life Expectancy指标下降。SQL Server为了提升性能,写入数据也是在缓冲区内完成的,不会直接写入到数据文件中,系统进程CHECKPOINT时再写入到数据文件,缓冲区空间不足时,就会触发Lazy Write进程,把数据写入到数据文件中并从缓冲区移除,Lazy writes/sec指标会上升。所以Page Life Expectancy指标下降和Lazy writes/sec指标会上升是缓冲区空间不足的表现。
解决
转到活动会话,查看当时正在执行的SQL语句, 大量的会话都存在PAGEIOLATCH_*相关的等待。PAGEIOLATCH_ *等待类型出现在数据从数据文件传输到缓冲区时。等待越多说明大量的数据都不在缓冲区内。
该服务器配置256GB内存,分配给缓冲区230GB,还出现如此严重的缓冲区空间不足,推断有一些SQL语句把大表整表的数据的数据都加载进缓冲区了。进入活动会话汇总视图,按照逻辑读进行排序, 发现几类新上线的报表类SQL语句,因为缺少合适的索引导致几张大表的全表扫描,要把整表的数据存入缓冲区,造成了缓冲区的压力。创建合适索引后问题解决,所有指标都恢复正常。
经验
很多时候磁盘是被冤枉的,因为低效的SQL或者物理内存本身不足导致内存压力,从而把压力转嫁到磁盘上,分析时一定要全面,Page Life Expectancy和Lazy writes/sec就是两个很重要的指标。
磁盘压力不是非常大的情况下,SSD盘响应时间在5毫秒左右,机械盘在30毫秒左右。如果通过性能指标发现磁盘读、写的量不大,但是响应时间却很长,那么基本可以确定是磁盘的性能问题。
索引的重要性强调多少遍都不为过,70%的情况下通过优化索引就能解决性能问题。在和大量的技术人员交流过程中发现,对于索引的重要性恰恰没有足够的重视,一提到优化就是修改SQL语句、读写分离、分布式数据库等舍近求远的方案,索引才是对数据库最高性价比的优化手段。