关于阿里云 RDS mysql索引优化的一点经验
2019年9月5日10:02:34
本地调试
git https://github.com/barryvdh/laravel-debugbar
composer require barryvdh/laravel-debugbar --dev
APP_DEBUG TRUE
配置.env
本地调试很方便,千万不要弄到线上去了,因为这个东西其实很消耗资源的
公司的项目,因为使用workerman做消息推送,我之前想是做主从,但是想到需要额外花费,而且目前大部分是内部使用,就开始了优化mysql之路
框架使用的是laravel5.7,基本都要求使用orm,但是框架里面还有有小部分使用的复杂使用的原生的,很多使用联表,注意这里的联表不是join联表,因为性能差异
查询使用的工具都是阿里云提供的工具
阿里云ApsaraDB诊断报告,SQL洞察分析,
ApsaraDB诊断报告对检查慢查询还是很有效的,很容易找到问题去优化
一个demo
SELECT * FROM `sale_out_storage` WHERE `shop_id` = ? AND `is_delete` = ? AND `storage_status` = ? AND NOT EXISTS ( SELECT * FROM `k3_sale_out_storage_task` WHERE `sale_out_storage`.`id` = `k3_sale_out_storage_task`.`sale_out_storage_id` AND `is_delete` = ? AND `is_cancel` = ? AND `status` IN (?) AND `shop_id` = ? ) AND EXISTS ( SELECT * FROM `sale_order` WHERE `sale_out_storage`.`sale_order_id` = `sale_order`.`id` AND `order_status` != ? ) AND `storage_date` > ? 建议 1. 返回记录数 语句最大返回记录数为55。
2. 行扫描 行扫描与行返回之比为178673。
3. 索引 该语句没有使用聚合函数和模糊查询,行扫描与行返回之比很高。创建合理索引会带 来很大的优化空间
|
SQL语句
|
数据库
|
线程ID
|
用户
|
客户端IP
|
操作
|
状态
|
耗时(ms)
|
执行时间
|
更新行数
|
扫描行数
|
|---|
|
select `id`, `user_id`, `admin_id`, `type`, `type_flag`, `content`, `operation_user_id`, `operation_admin_id`, `is_read`, `shop_id`, `message_tag`, `message_type`, `create_time` from `operation_log` where `admin_id` = 14 and `operation_admin_id` != 14 and `is_read` = 1 and `message_type` in (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19) and `create_time` >= '2019-06-01 00:00:00' order by `id` desc limit 10 offset 0
|
v2
|
60130
|
youse
|
172.18.112.8
|
SELECT
|
成功
|
0.25
|
2019年9月6日 10:57:50
|
0
|
13
|
|
select count(*) as aggregate from `operation_log` where `user_id` = ? and `is_read` = ?
|
v2
|
24
|
youse
|
172.18.112.8
|
SELECT
|
成功
|
0.04
|
2019年9月6日 10:57:50
|
0
|
0
|
|
select * from `sale_voucher` where `is_delete` = 10 and `shop_id` = 1 and `admin_id` = 14 and `status` = 30 and `create_time` >= '2019-01-01' order by `id` desc limit 5 offset 0
|
v2
|
60130
|
youse
|
172.18.112.8
|
SELECT
|
成功
|
0.48
|
2019年9月6日 10:57:50
|
0
|
289
|
|
select `id`, `user_id`, `admin_id`, `type`, `type_flag`, `content`, `operation_user_id`, `operation_admin_id`, `is_read`, `shop_id`, `message_tag`, `message_type`, `create_time` from `operation_log` where `admin_id` = ? and `operation_admin_id` != ? and `is_read` = ? and `message_type` in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) and `create_time` >= ? order by `id` desc limit 10 offset 0
|
v2
|
60130
|
youse
|
172.18.112.8
|
SELECT
|
成功
|
0.12
|
2019年9月6日 10:57:50
|
0
|
0
|
|
|
||||||||||
|
select * from `admin_permission` where `is_delete` = 10 and `id` in (1, 3, 69, 148,, 439, 440, 428, 429, 430, 431, 432, 433, 444, 115, 244, 245, 246, 247, 248, 249, 239, 389, 390, 129, 331, 332, 333, 334, 391, 392, 393, 394, 395, 149)
|
v2
|
60130
|
youse
|
172.18.112.8
|
SELECT
|
成功
|
1.04
|
2019年9月6日 10:57:50
|
0
|
527
|
我发现的最大的问题有以下几点:
1,where in的性能其实很差,经常需要大范围扫描,减少in的范围,或者使用exists代替
2,使用时间范围查询的时候一定要加上索引,不然效率很差,大范围扫描行数
3,索引不能添加过多,过多也会导致性能下降,比如log日志表,提供给多方查询的时候,添加过多,mysql内部多个索引进行查询的时候,会增加计算量,大大消耗cpu
4,如果有多个索引比如订单表,请注意一定优先最左原则,最大化利用索引,强调代码规范
5,join 会大大增加内存消耗,即使在符合大表连小表的原则
6,适当添加索引,特别是在laravel with联表的时候
$parent_sale_order_info = SaleOrder::where('shop_id', $shop_id)->where('is_delete', 10)
->with([
'sale_order' => function ($query) {
$query->where('is_delete', 10)->with([
'sale_out_storage' => function ($query) {
$query->where('is_delete', 10)->where('storage_status', 20)->with([
'sale_out_storage_sku' => function ($query) {
$query->where('is_delete', 10);
}
]);
},
'sale_pay' => function ($query) {
$query->where('is_delete', 10);
}
]);
},
'sale_settle' => function ($query) {
$query->where('is_delete', 10)->with([
'sale_settle_sku' => function ($query) {
$query->where('is_delete', 10);
}
]);
},
'sale_pay_record' => function ($query) {
$query->where('is_delete', 10)->where('status', 20);
}
])
->where('id', $parent_order_id)
->first();
优化完的结果

有日常80%-95%,优化完之后30%上下,阿里云的rds mysql 5.7,2核4g
补充一点,核心的解决办法就是找到出问题点在哪,我这个场景就是因为推送大大增加数据查询消耗,导致mysql扫描行大大增加
解决思路如下:了解业务的繁忙点,找到频繁的核心表,优先尝试,优化索引,这样的就不需要修改很多代码,如果发现只优化索引不能解决,坚决修改代码,并指导开发人员是为什么需要这样写
更改书写习惯和理念,这样才能根本解决问题,不然只是临时救火。
一点参考的文章
https://www.cnblogs.com/ManyQian/p/9076247.html#_label2
https://www.cnblogs.com/ManyQian/p/9038063.html
https://www.cnblogs.com/ManyQian/p/9026606.html
https://www.cnblogs.com/zjxiang/p/9160810.html
关于阿里云 RDS mysql索引优化的一点经验的更多相关文章
- 记阿里云 RDS MySQL 的一个大坑
花了一个下午的时间,终于把一个阿里云 RDS MySQL 的一个大坑填上了,解决方法令人匪夷所思!绝对会让各位看官感到大吃一惊,阿里云 RDS MySQL 居然有这样 xx 的大坑! 问题 最近应业务 ...
- 阿里云rds mysql数据库数据恢复到ecs中
背景:aliyun上的rds数据库快满了,于是删除了某个备份的表后面大boss说是有用的表,需要恢复回来,阿里云有7天内的物理全量备份(通过percona-xtrabackup备份的)第一时间应该延长 ...
- 再也不怕数据丢失!阿里云RDS MySQL 8.0上线回收站功能
背景 MySQL 在生产环境使用过程中,会伴随着开发和运维人员的误操作,比如 DROP TABLE / DATABASE,这类 DDL 语句不具有可操作的回滚特性,而导致数据丢失,AliSQL 8.0 ...
- 为更强大而生的开源关系型数据库来了!阿里云RDS for MySQL 8.0 正式上线!
2019年5月29日15时,阿里云RDS for MySQL 8.0正式上线,使得阿里云成为紧跟社区步伐,发布MySQL最新版本的云厂商.RDS for MySQL 8.0 产品是阿里云推出的 MyS ...
- 使用阿里云RDS for SQL Server性能洞察优化数据库负载-初识性能洞察
简介 数据库性能调优通常需要较高数据库水平,并伴随较多的前期准备工作,比如收集各种性能基线.不同种类的性能指标.慢SQL日志等,这通常费时费力且效果一般,当面对多个数据库时总体拥有成本会大幅增加.今天 ...
- 阿里云 RDS for MySQL支持什么引擎
问题:我们的服务器是买的是阿里云,mysql版本5.011 ,本地和服务器配置一样,在本地可以安装discuzX3.4,但是在服务器上却报错了,如下图: 找了半天,才知道阿里云RDS 支持的mysql ...
- 阿里云 RDS for MySQL 物理备份文件恢复到自建数据库
想把阿里云的Mysql 生成的RAS 文件.tar文件 恢复到本地自建mysql, 遇到的坑.希望帮助大家 阿里云提供的地址 https://help.aliyun.com/knowledge_det ...
- 阿里云RDS的mysql数据库占用空间超过90%的处理
阿里云RDS数据库最大支持2T,目前已经占用了90%,如果进行分库或者迁移比较麻烦,思路是找出占用空间过大的日志或不重要的文件进行删除操作 查询所有数据库占用磁盘空间大小的SQL语句: show bi ...
- 阿里云RDS数据库改造迁移方案
1. 改造原因 (1) 由于历史原因, 本应该是同一个库的表分布在两个数据库中,需要对这两个库进行合并. (2) 已有的数据库性能无法满足业务的增长需要, 查询卡,慢问题突出. (3) 当前自建Mys ...
随机推荐
- Graylog-centos安装
graylog安装 1.先决条件 yum install java-1.8.0-openjdk-headless.x86_64 -y #安装java软件包 yum install epel-relea ...
- centos安全加固
设置SSH登录超时时间 /etc/profile export TMOUT=900 设置账户密码策略 /etc/login.defs PASS_MAX_DAYS 180 PASS_MIN_DAYS 0 ...
- wordpress默认css样式class和id集合
你是否想过如何设计WordPress主题的不同元素?每个主题都不一样,但是有一些CSS的class和id是由WordPress生成的.我们将逐一介绍一些最重要的默认WordPress样式,方便初学者快 ...
- MapReduce内存调优
内存调优 Hadoop处理数据时,出现内存溢出的处理方法?(内存调优) 1.Mapper/Reducer阶段JVM内存溢出(一般都是堆) 1)JVM堆(Heap)内存溢出:堆内存不足时,一般会抛出如下 ...
- Spring全家桶相关文章汇总(Spring,SpringBoot,SpringData,SpringCloud)
因为Spring框架包含的组件比较多,写的博客内容也比较多,虽然有分专栏但是依然不方便查找,所以专门用一篇文章来记录相关文章,会不定期更新. 一.Spring 1.基础内容 Spring介绍 Sp ...
- webapi HttpGet标签
该标签可以指定路由如HttpGet["Test"],以前用的很顺,后来加了Area后,按照area/controller/Test的路径去访问报404,原因是HTTPGet指定路由 ...
- 8259A的初始化(单片)
1.单片8259A的初始化流程图: 在单片的初始化中不需要ICW3,因为ICW3是指明主片和从片的连接情况的. 2.程序解析: (1)ICW1 MOV AL,13H (2)ICW2 MOV AL,08 ...
- Aquameta 基于postgresql的web 开发平台
Aquameta 是一个完全基于pg 开发的web平台 ,目前还在开发中. 当前支持的功能 meta 写入系统信息到pg bundle 基于pg 类似git 的文件系统 filesystem 双向文件 ...
- The Ultimate Guide to handling JWTs on frontend clients (GraphQL)
转自:https://blog.hasura.io/best-practices-of-using-jwt-with-graphql/ hasura 团队关于jwt 的实践 JWTs (JSON We ...
- webpack配合babel使用
一.babel介绍 ①Babel 是一个 JavaScript 编译器,可以把ES6的语法转为兼容浏览器的ES5语法 ②Babel中文官网:https://www.babeljs.cn/ ③Babel ...