数据库查询性能优化一直是程序员绕不开的话题,当咱们遇到业务刷新报表缓慢或者查询获取结果延迟太大,能够采用提问法来思考如何进行优化。
ios
1. 什么样的环境
硬件环境
query执行的速度和咱们的硬件息息相关,当前用的什么样的CPU,有多少核多少线程, 内存有多大都直接影响了运算速度, 磁盘是SSD仍是HDD,网卡什么速率都直接影响了咱们数据读取的时延程序员
软件环境
软件环境虽然不像硬件同样,各类参数看的见摸得着,但仍然影响着咱们的查询性能。没一套系统实际上都在特定的场景有着各自的优点。咱们的查询系统是什么样的架构,适合什么样的query,在线仍是离线, 计算多仍是数据读取多,这些在咱们作优化的时候都应该了然于心。web
下面咱们根据这种思路来看看如何作性能优化数据库
2. 什么样的query
首先咱们优化查询的时候,须要看看query 到底是哪一种类型。写入仍是查询(这里鉴于篇幅只谈查询), CPU密集仍是IO密集。若是咱们的系统是适合OLTP低延时点查的场景, 想要在这种系统上作OLAP大规模分析很显然就不太适合, OLTP通常专一于数据一致性较高的点查,而OLAP因为数据量庞大,通常都须要采用向量并发查询。OLAP不专一于毫秒级的低延迟, 而OLTP不专一于上亿级的数据统计。性能优化
3. 如何寻找性能瓶颈
3.1 vmstat查看系统状况
总体系统不知道当前的瓶颈在哪里时, 咱们能够先用vmstat工具来简单的看一下系统的大体状况。以下图所示,2表示每一个两秒采集一次服务器状态。服务器
procs : 查看进程状态
r : 运行队列,即当前可运行(正在运行或者等待运行)的进程数量。目前CPU比较空闲,这个数量很小,当这个值超过了CPU数目,就会出现CPU瓶颈了。微信
b : 阻塞的进程,即处在不可中断sleep状态下的进程数量。网络
memory : 查看内存状态
swpd : 已使用的虚拟内存大小,若是大于0,表示机器开始使用虚拟内存了,虚拟内存运行会很慢。这里数值为0表示咱们关闭了虚拟内存功能。session
free : 空闲的物理内存的大小。数据结构
buff : 内存作为系统buffers的大小。
cache : 内存作为系统cache的大小。
swap : 磁盘和内存作数据交换的状态
nesi : 每秒从磁盘读入虚拟内存的大小,若是这个值大于0,表示物理内存不够。
so : 每秒虚拟内存写入磁盘的大小。
io:磁盘的io信息
bi : 每秒从块设备接收的块数量。
bo : 每秒发送给块设备的块数量。
若是这两个值较大,表示IO比较频繁,能够考虑IO优化。
system : 系统状态信息
in : 每秒CPU的中断次数(包括时钟中断)
cs : 每秒上下文切换次数,咱们调用系统函数、线程的切换,就须要上下文切换,这个值要太大就能够考虑 减小系统的上下文切换,好比协程替代多线程等方式。
CPU : CPU信息
us : 包括用户时间和nice时间,跑非内核的代码(或者用户代码)的时间。
sy : 系统占用时间,跑内核代码(好比系统调用)占用的时间。
id : 花费在idle上的 CPU时间。
wa : 等待IO CPU时间。若是这个值太大,表示IO系统瓶颈在IO上。
若是CPU占用高表示系统在CPU上, 若是系统的swap比较频繁,极可能是系统内存泄露或者内存不够用,须要扩展内存, 若是是IO等待较多则系统瓶颈出如今IO上,若是上下文切换,或者系统调用占比太大,则咱们须要思考下咱们程序的设计,减小系统调用或者上下文切换。
3.2 CPU占用太高
咱们能够经过uptime、top、mpstat或者sar等一些工具来查看当前CPU占用太高的状况.
咱们能够经过uptime看看当前系统的总体状况, 当前的系统时间和运行时间, 登录的用户数量,还有最近五、10和15分钟的系统平均负载。
top则能够显示较详细的信息。head部分有CPU占用的详细信息, 下面的列表也有记录每一个进程占用的CPU状况。
若是是多线程, 咱们还能够经过top -H -p pid来查看进程的每一个线程的CPU占用状况
咱们找到哪一个线程占用的比例多以后, 能够根据这个线程的线程名查看该线程是用来作什么处理的。大体了解下是什么样的处理让CPU比较高。
mpstat则能够查看系统每一个核的运行状态。
sar的功能比较全,这里再也不作科普。
CPU用户态的占用比较高,通常就是咱们的程序编写的效率过低,具体哪里低,咱们能够经过perf工具或者Intel的vtunes来查看性能瓶颈。perf top的执行结果以下图所示, 咱们拿到对应的堆栈信息以后, 就能够针对性的消除CPU瓶颈了。(vtune的用法能够自行谷歌)。
鉴于上述工具检查出来的状况, 若是CPU确实水位很高,则CPU基本就是性能瓶颈。若是不高则,须要进行下一步来判断性能瓶颈。
3.3 IO占用太高的状况
IO定位的工具多种多样, 通常查看IO问题咱们可使用iostat、pidstat和iotop工具。固然咱们也可使用其余的工具,你们能够本身搜索相关的工具使用, 这里主要介绍经常使用的几种工具。
pidstat
pidstat是sysstat工具的一个命令,用于监控所有或指定进程的cpu、内存、线程、设备IO等系统资源的占用状况。用户能够经过指定统计的次数和时间来得到所需的统计信息。
咱们经过这个命令能够知道哪一个进程占用的IO比较多。而后咱们能够经过指定进程号的方式查看更详细的信息。
这样咱们就能够知道是哪一个进程中的哪一个线程占用了较多的IO资源,而后咱们能够经过对应的TID,找到对应的执行代码进行分析。
iostat
iostat是I/O statistics(输入/输出统计)的缩写,它能够对系统的磁盘操做活动进行监控,汇报磁盘活动统计状况。可是iostat仅对系统的总体状况进行统计,不能对某个进程进行深刻分析,单独的进程分析咱们能够用iotop工具,使用方法和top相似。
1 表示每秒打印一次当前磁盘的统计信息。咱们须要注意的是后面几个指标。
avgrq-sz | 平均每次IO操做的数据量(扇区数为单位) |
---|---|
avgqu-sz | 平均等待处理的IO请求队列长度 |
await | 平均每次IO请求等待时间(包括等待时间和处理时间,毫秒为单位) |
svctm | 平均每次IO请求的处理时间(毫秒为单位) |
%util | 采用周期内用于IO操做的时间比率,即IO队列非空的时间比率 |
左右滑动查看完整表格
avgrq-sz直接反应了当前io的种类,好比大块数据读取仍是小数据量的读取。
avgqu-sz反应了当前IO的繁忙状况, 若是队列长度太长,说明IO如今很忙不少任务处理不过来,换句话说 I,IO成为了瓶颈。
await 也是同样, 若是等待比较高,说明IO成了累赘。
svctm则和avgrq-sz同样,反应了IO操做的处理规模,若是是大块数据读写, 这个时间就会拉长。
iotop
iotop 能够用于查看哪些进程执行占用了的 I/O,使用方式和top相似,这里再也不作过多描述。
3.4 其余状况
若是TOP占用不高, IO也不是瓶颈,则可能处在程序架构上, 好比并发控制的不够好有较多的线程在sleep状态。这种状况能够经过pstack看看当前全部线程的堆栈。
4. 优化性能瓶颈
CPU瓶颈型
面对这种类型,通常咱们须要经过perf配合对应的代码去进行优化,核心思想就是减小计算的量。具体方法如下仅供参考:
多采用SIMD来代替老式的计算指令或者C++的操做运算符。能够引进相似Intel的MKL库来辅助计算。
减小没必要要的重复计算,减小for循环的次数。好比有些std库的数据结构都有find函数都带有起始坐标,善用起始坐标避免从0坐标重复查询。
若是是系统调用过多,好比分配内存之类的,能够考虑预分配内存的方式,或者直接使用tcmalloc等相似的内存管理库进行兜底,有条件的能够基于这类库再开发适合本身的内存管理体系
IO瓶颈型
IO瓶颈通常都是和磁盘相关的,网络上,由于网卡升级,速度上去比较快,相比来讲,限制的io基本都是磁盘上的io.下面也只说说磁盘的IO优化方法。
若是是读类型的请求形成了IO瓶颈, 能够考虑上层多开cache。好比全局的query cache, session级别的session cache, 块设备的block cache等,从上层去减小磁盘的io请求。
若是是是小数据大并发的写入类型的形成了IO瓶颈,咱们能够考虑在内存作一次cache,对这屡次写入先在内存处理,而后经过时间或者大小阈值等策略控制,刷到磁盘上。
若是是大数据的写入,咱们能够考虑作下平滑写入,每次限制写入的数量。
若是是由于流量的关系,某一时间点出现峰值,以后回落,则能够考虑经过第三方来写入。好比消息队列,先写到消息队列i进行削峰,再平滑写入系统。
除此以外咱们还能够换更好的硬件,好比磁盘阵列等。
内存瓶颈型
内存瓶颈通常比较难出现,内存毕竟比较便宜,基本上都会知足内存的需求。若是真的由于虚拟内存的问题形成了程序运行效率低下,咱们一方面是考虑增长内存,关闭虚拟内存来解决,同时咱们也应该思考本身的程序模型,好比减小中间数据的存在, 多用写时复制技术,多用用系统的no copy接口替换老的接口等。
5. 后续
若是实在没有方法优化了,咱们真的就须要看看当前的query是否真的合适咱们的系统了。仍是那句话,每套系统都有适合本身的业务,通常公司的系统体系里都会有多种数据库引擎,针对咱们的query,去寻找合适的引擎也是一种方法。
☆ END ☆
OPPO互联网技术团队招聘一大波岗位,涵盖C++、Go、OpenJDK、Java、DevOps、Android、ElasticSearch等多个方向,请点击这里查看详细信息及JD。
更多技术干货
扫码关注
OPPO互联网技术


本文分享自微信公众号 - OPPO互联网技术(OPPO_tech)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。