本博文主要是针对,mysql中高cpu、高内存、高io、高sleep等复杂场景进行常用的优化设计方案的说明介绍。
一、占用CPU100%的优化 1.1 总体思路1、先用操作系统命令 top 观察是不是 mysqld 占用导致的,如果不是,找出占用高的进程,并进行相关处理。
2、如果是mysqld 造成的,show processlist,看看里面跑的 session 情况,是不是有消耗资源的 sql 在运行。
找出消耗高的 sql,看看执行计划是否准确, index 是否缺失,或者实在是数据量太大造成。
SHOW PROFILES\G查看queryid,sqltext,接着show profile cpu,block io for query 2;查看消耗情况。
3、一般来说,肯定要 kill 掉这些线程(同时观察 cpu 使用率是否下降),等进行相应的调整(比如说加索引、改 sql、改内存参数)之后,再重新跑这些 SQL。
4、也有可能是每个 sql 消耗并不多,突然大量的 session 连进来使 cpu 飙升,需要跟应用一起分析为何连接数会激增,再做相应调整,比如说限制连接数等。
5、补充:SQL语句分析三板斧explain+show processlist+show profile for query query_id。
1.2 使用 show processlist1、查看当前哪些线程正在运行。查看下来一共有160多个
mysql> show processlist;
+----+------+-----------+------+---------+------+-------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+------+-----------+------+---------+------+-------+------------------+
state只是sql执行中的某一个状态,以查询sql为例,可能需要经过copying to tmp table,Sorting result,Sending data等状态才可以完成。
由于在Sending data状态下,MySQL线程往往需要做大量的磁盘读取操作,所以经常是整个查询中耗时最长的状态。
2、从show processlist命令输出的结果看到有一条sql语句重复出现,但是info列显示的不全只有select a.col1,a.col2,a.col3 from table1 a这样的信息。那就先从这个表入手查,select count(*) from table1;查出这张表有60W+的数据。select count(*) 使用了6秒。但是现在不确定这个语句执行的时候有没有where条件。
3、再查询information_schema.processlist表时发现info信息是完整的,在这里找到上边怀疑的sql的完整版为select a.col1,a.col2,a.col3 from table1 a where a.col4='123' and a.col5='abc';
查看这个语句的执行计划(类似下面这种)
mysql> explain select ename,hiredate,sal from table1 where sal=1000 \G;
type: ALL全表扫描,没有使用索引
4、哪种type性能好
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
ALL——全表扫描
index——索引全扫描
range——索引范围扫描,常用语 show index from table1;
2、表的存储引擎为 InnoDB,于是在col4列上创建索引
mysql> show table status from table1 like 'table1';
Engine: InnoDB存储引擎
3、加索引
mysql> create index idx_sal on table1(col4);
4、再次查看执行计划,发现语句使用索引扫描。
mysql> explain select * from table1 where col4=1000 \G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE # 连接类型
table: emp
type: ref # 建索引之前是:type: ALL全表扫描
possible_keys: idx_sal
key: idx_sal
key_len: 6
ref: const 主键或唯一索引查询
1.4 sql语句的执行效率立马提升。CPU的使用率也降下来了。
1.5 高CPU占用总结
cpu消耗过大有慢sql造成,慢sql包括全表扫描,扫描数据量太大,内存排序,磁盘排序,锁争用等;表的现象:
sql执行状态为:sending data,copying to tmp table,copying to tmp table on disk,sorting result,using filesort,locked;
1、sending data
sql正从表中查询数据,如果查询条件没有适当索引,会导致sql执行时间过长
2、copying to tmp table on disk:
因临时结果集太大,超过数据库规定的临时内存大小,需要拷贝临时结果集到磁盘上
3、sorting result,using filesort:
sql正在执行排序操作,排序操作会引起较多的cpu消耗,可以通过添加索引,或减小排序结果集。
所以如果用户的数据量很大,内存很小,因iops的限制,一条慢sql就有可能消耗掉所有io资源,而影响其他sql查询,
对于数据库就是所有的sql需要执行很长时间才返回结果集,对于应用会造成整体响应变慢。
二、大量的sleep进程的优化 博文参考简单总结mysql高cpu高mem高io高sleep常用的优化手段 - 文章详情