美文网首页
MySQL高CPU占用排查——索引的重要性

MySQL高CPU占用排查——索引的重要性

作者: lsyarn | 来源:发表于2019-12-10 22:29 被阅读0次

    划重点:

    建表时考虑怎么查询,给必要的字段创建索引可以提升查询效率,减小加锁的范围,降低加锁的时间

    使用explain解释sql语句可以查看是否使用了索引

    索引不仅仅为了提高查询速度,使用索引避免全表锁可以提高查询、更新操作的效率

    最近一段时间涉及的ES的查询任务都变的异常慢,很多定时任务都比原来多出几个小时的执行时间。一直在排查ES的问题,但是没有找到哪个新增的操作会导致ES性能下降。由于有一台服务器部署了2个ES节点和一个mysql,这台服务器的负荷一直以来都比较高,当看到这台服务器高负荷时并没有终点关注。后来,使用top命令查看进程时,发现mysql占用了800%的cpu时间,意识到是mysql的哪个操作出现问题了。排查步骤如下:

    1. show porcesslist

    使用show porcesslist,看看有没有长时间执行的任务。发现有好几条查询语句处于sending data状态持续了2000多秒,第一反应就是这个表没有索引。一查表结构果然如此,分析一下查询语句添加索引吧。

    问题又来了,添加索引的语句执行了半天没有反应,show porcesslist发现语句正在获取锁。无奈至下把关于这个表的所有任务都kill掉,然后再创建索引,然后成功了,添加索引后原来执行30分钟的任务只需要5秒。

    回过头来再分析一下原因,我挑了设计改表的2个sql语句,如下:

    UPDATE 
          `iptv_alarm` 
        SET
          olt_ip = '{ip}' 
        WHERE dev_code = '{code}'
        AND olt_ip is NULL
    
    SELECT 
          * 
        FROM
          `iptv_alarm` A 
        WHERE eventtime = 
          (SELECT 
            MAX(eventtime) 
          FROM
            `iptv_alarm` B 
          WHERE A.dev_code = B.dev_code 
            AND A.clearancereportflag = 0 
            AND A.dev_type = 2 
            AND gte_five = 0 
            AND rk_time > '{start_time}' 
            AND rk_time <= '{end_time}' 
            AND dev_code IN ({olt_list})) ;
    

    上面一个是更新语句,下面一个是查询语句。由于没有索引,每次查询时创建共享锁(表锁),每次更新时创建排它锁(表锁)。由于两个语句执行都比较频繁,mysql就疲于申请锁、加锁、释放锁之间,cpu都被它吃了。再看添加索引后,我新增了rk_time,dev_code两个字段的索引,实际查询时只使用了dev_code的索引。有了索引之后,查询和更新语句都可以申请行锁,而不用对整个表加锁,另外查询效率也快了,整体效率自然提升上去了。

    另外,整个表只有3万条数据,数据量并不大。所以无论数据量大小,建表时一定要考虑好整个表要怎么使用,创建必要的索引。

    推荐阅读:

    MySQL 表锁和行锁机制

    相关文章

      网友评论

          本文标题:MySQL高CPU占用排查——索引的重要性

          本文链接:https://www.haomeiwen.com/subject/hlsngctx.html