MySQL调优笔记

您所在的位置:网站首页 阿里巴巴druid修改表名 MySQL调优笔记

MySQL调优笔记

2023-04-26 04:11| 来源: 网络整理| 查看: 265

上周,项目出现线上问题,在这家公司做的是一个SAAS平台,总用户量大约10万人;

经过排查,发现是SQL问题,导致数据库响应慢,进而拖垮了整体服务;

通常,查询耗时较长的SQL涉及到的一些常见原因包括但不限于:数据量过大,查询未使用索引等

于是我们组开始全面摸牌对数据库查询性能影响较大的SQL,一些步骤记录如下:

1. 分析大数据库表SELECT TABLE_NAME '表名', DATA_LENGTH '数据长度', INDEX_LENGTH '索引长度', (DATA_LENGTH + INDEX_LENGTH) AS '总长度', TABLE_ROWS '行数', CONCAT(ROUND((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024, 3), 'MB') AS '占用空间'FROM information_schema.TABLESWHERE TABLE_SCHEMA = '${你的数据库名称}'ORDER BY (DATA_LENGTH + INDEX_LENGTH) DESC;

        使用以上SQL可以查询出数据库的数据表统计信息,这个数据不是最新的但是接近最新,可以做一个大致的数据量参考,执行结果大致如下:

基本上看占用空间或者数据行数,总量排名靠前的表是重点关注对象。

2. 查看阿里云数据库运行监控

        通过阿里云的云数据库监控工具导出了一份SQL的执行监控,用过阿里巴巴druid连接池的都知道,主要就是用来分析SQL的执行时长和执行频率的;

这是一份2分钟执行记录的数据库执行记录,重点关注执行次数、执行时长,针对性优化

3.  SQL优化

通过阿里云的数据库运行监控导出的监控记录,一条条优化,这里列举一条

SELECT * FROM device_p350_real_time_data a WHERE record_time = (SELECT max(record_time) FROM device_p350_real_time_data WHERE project_id = '32641235' ) AND project_id = '32641235' ORDER BY record_time desc

这条SQL在监控中显示,平均执行 2秒,执行次数146秒;

3.1 EXPLAIN分析一下执行计划

 可以看到,这个子查询 ( select max(record_time) from xxx) 扫描了接近300万行数据,造成了巨大的性能消耗;

3.2 分析一下SQL对应的业务

我这里的SQL是要获取当前物联网数据表中最新的一批数据,于是使用了where record time = max(record_time) 这样的写法,虽然record_time增加了索引,但是聚合函数没有用到索引,因此造成了全表扫描,子查询严重拖累了速度;

于是将这里的子查询逻辑稍作修改,将 where record_time = (select max(record_time) from xxx) 变成 where record_time = (select record_time from xxx order by record_time desc limit 1)

这样之后,由于MySQL对索引字段是使用的B+排序树,所以子查询只扫描一行数据;

再次EXPLAIN:

执行耗时:0.371s

至此,一个最小单位的SQL优化已经结束,对1和2步骤扫描出来的 大表、执行耗时长的SQL重复进行类似3步骤的针对性调优,最终可以把整个系统的慢SQL都降下来,提高服务稳定性;

总结的话,就是尽量用到索引,编写查询语句的逻辑尽量使用更少的数据行扫描,不要对索引字段使用函数;



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3