一次难得的MySQL优化初实践

Posted androidstarjack

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一次难得的MySQL优化初实践相关的知识,希望对你有一定的参考价值。


 

 

点击上方关注 “终端研发部

设为“星标”,和你一起掌握更多数据库知识

去年项目重构,系统切换为微服务架构,数据库各方面也做了分库分表的一些实践,感觉那段时间写代码酣畅淋漓,爽,然,老系统依然需要继续维护,看目前情况,两个系统可能会在未来几年时间内同时对用户提供。我们开发没意见,一切为运营服务(内心OS:产品和运营大大们能不能尽快推进切换啊,毕竟老一套还要写JSP,这其中酸爽,难以体会)。

如何将2万条数据快速导入到 MySQL?

这日,老大丢了一条慢查询SQL语句,说老系统服务中的这条SQL语句查询超过4s+了,看看业务中具体那儿在用并确认一下是否存在优化空间,具体查询语句示例如下(业务安全问题,不可对外展示):

select o.attr1,o.attr2,o.attr3, u.attr4, u.attr5 from order o outer join user u on 
o.u_id=u.id and o.createAt>='2022-03-20 00:00:00' and o.status="success" and o.feeType='TV' and o.payType='ali_pay' ....

该业务的主要功能是定时每5s定时从三方更新用户会员订购权益。好的,领下任务,遂开始在测试环境上执行查看了一下SQL语句的执行计划,

id  select_type table   type        possible_key    key      key_len ref         rows   Extra
1    SIMPLE        this_    index                        PRIMARY     4                   56    Using where
1    SIMPLE        user2_    eq_ref        PRIMARY            PRIMARY        4    this_.user_id    1    Using where

测试环境就是只有50多条测试订购单数据,看起来,虽然是使用了主键索引,但是rows范围是整个表,这个主要是查询语句中的根据订单表的id进行了降序排序,去掉排序就可以看出来,实际上就是全表扫描了无疑:

id  select_type table   type        possible_key    key      key_len ref         rows   Extra
1    SIMPLE        this_    index                        ALL     4                   56    Using where
1    SIMPLE        user2_    eq_ref        PRIMARY            PRIMARY        4    this_.user_id    1    Using where

好吧,让运维确认了现网订购单表数据,达到340W+条,查询时间达到4.737s,这个量级,全表扫描是无法接受的,且目前每天以超过1w左右的量持续增加,这种情况,必须查询优化了,优化第一C位,必须是利用索引呀。目前订单表除了默认id主键,在user_id字段上加了索引,用于业务关联查询,但对目前这个需求来说,无法有效减少扫描范围,需要考虑新建索引。确定建立怎样的索引?

  1. 查询条件中有多个条件:status(订单状态),payType(支付类型) feeType(计费类型) createAt(订单创建时间),除了createAt,其他几个字段均是枚举类型值,根据索引创建原则,枚举值类型的字段自然不合适,所以createAt是作为创建索引的最佳字段

  2. 根据现有业务,考虑创建的索引能否服务更多的业务需求?重新整体梳理整个服务应用,订单表还有如下应用:

  • 查询渠道某个时间范围的支付成功情况(1处,应用频率较低,主要用于运营后端查询)

  • 查询某个用户TV付费服务类型订购成功记录(1处,定时每30s执行一次)

  • 根据时间范围查询TV端订购记录(1处,定时每30s执行一次)

所以结合具体的业务形态,决定使用复合索引进一步来提升索引复用和查询共用能力。索引创建如下:

alter table order add index time_user_status_idx(createAt,user_id,status)

确定了处理思路,找老大讨论了一下,比较服务目前的业务情况,那就和晚上的服务上线一并处理了,凌晨12点,运维同学传来捷报,执行时间为0.001s,OK,收工。虽然这次的优化不是非常深入,但是也确实明白了业务中当数据量上来后性能优化的重要性。未来的开发路漫长,需要多多思考。

本文转自 https://juejin.cn/post/7077917522439176228,如有侵权,请联系删除。

回复 【idea激活】即可获得idea的激活方式
回复 【Java】获取java相关的视频教程和资料
回复 【SpringCloud】获取SpringCloud相关多的学习资料
回复 【python】获取全套0基础Python知识手册
回复 【2020】获取2020java相关面试题教程
回复 【加群】即可加入终端研发部相关的技术交流群
阅读更多
用 Spring 的 BeanUtils 前,建议你先了解这几个坑!

lazy-mock ,一个生成后端模拟数据的懒人工具

在华为鸿蒙 OS 上尝鲜,我的第一个“hello world”,起飞!

字节跳动一面:i++ 是线程安全的吗?

一条 SQL 引发的事故,同事直接被开除!!

太扎心!排查阿里云 ECS 的 CPU 居然达100%

一款vue编写的功能强大的swagger-ui,有点秀(附开源地址)


相信自己,没有做不到的,只有想不到的在这里获得的不仅仅是技术!



喜欢就给个“在看”

以上是关于一次难得的MySQL优化初实践的主要内容,如果未能解决你的问题,请参考以下文章

小试牛刀(初)

IPFS实践之初体验

再次实践 MySQL chart - 每天5分钟玩转 Docker 容器技术(166)

谈谈如何优化MYSQL数据库查询

数据库优化的常见误区

cocos2d-x ios游戏开发初认识 渲染的优化