转载自公众号:不一样的科技宅

前言

今天我们聊一聊Mysql大表查询优化,前段时间应急群有客服反馈,会员管理功能无法按到店时间、到店次数、消费金额 进行排序。

经过排查发现是Sql执行效率低,并且索引效率低下。

应急问题

商户反馈会员管理功能无法按到店时间、到店次数、消费金额 进行排序,一直转圈圈或转完无变化,商户要以此数据来做活动,比较着急,请尽快处理,谢谢。

线上数据量

merchant_member_info 7000W条数据。
member_info 3000W。

不要问我为什么不分表,改动太大,无能为力。

问题SQL如下

SELECT  mui.id,  mui.merchant_id,  mui.member_id,  DATE_FORMAT(  mui.recently_consume_time,  '%Y%m%d%H%i%s'  ) recently_consume_time,  IFNULL(mui.total_consume_num, 0) total_consume_num,  IFNULL(mui.total_consume_amount, 0) total_consume_amount,  (  CASE  WHEN u.nick_name IS NULL THEN  '会员'  WHEN u.nick_name = '' THEN  '会员'  ELSE  u.nick_name  END  ) AS 'nickname',  u.sex,  u.head_image_url,  u.province,  u.city,  u.country
FROM  merchant_member_info mui
LEFT JOIN member_info u ON mui.member_id = u.id
WHERE  1 = 1
AND mui.merchant_id = '商户编号'
ORDER BY  mui.recently_consume_time DESC / ASC
LIMIT 0,  10

出现的原因

经过验证可以按照“到店时间”进行降序排序,但是无法按照升序进行排序主要是查询太慢了

主要原因是:虽然该查询使用建立了recently_consume_time索引,但是索引效率低下,需要查询整个索引树,导致查询时间过长。

DESC 查询大概需要4s,ASC 查询太慢耗时未知。

为什么降序排序快和而升序慢呢?

因为是对时间建立了索引,最近的时间一定在最后面,升序查询,需要查询更多的数据,才能过滤出相应的结果,所以慢。

解决方案

目前生产库的索引

调整索引

需要删除index_merchant_user_last_time索引,同时将index_merchant_user_merchant_ids单例索引,变为 merchant_id,recently_consume_time组合索引。

调整结果(准生产)

调整前后结果对比(准生产)

测试数据

merchant_member_info 有902606条记录。
member_info 表有775条记录。

SQL执行效率

优化前

优化后

type由index -> ref

ref由 null -> const

调整索引需要执行的SQL

执行的注意事项:

由于表中的数据量太大,请在晚上进行执行,并且需要分开执行。

# 删除近期消费时间索引
ALTER TABLE merchant_member_info DROP INDEX index_merchant_user_last_time;  # 删除商户编号索引
ALTER TABLE merchant_member_info DROP INDEX index_merchant_user_merchant_ids;  # 建立商户编号和近期消费时间组合索引
ALTER TABLE merchant_member_info ADD INDEX idx_merchant_id_recently_time (`merchant_id`,`recently_consume_time`);

经询问,重建索引花了30分钟。关注公众号互联网架构师可以获取系列索引教程。

最终的分页查询优化

上面的sql虽然经过调整索引,虽然能达到较高的执行效率,但是随着分页数据的不断增加,性能会急剧下降。

最终的sql

优化思路:先走覆盖索引定位到,需要的数据行的主键值,然后INNER JOIN 回原表,取到其他数据。

SELECT  mui.id,  mui.merchant_id,  mui.member_id,  DATE_FORMAT(  mui.recently_consume_time,  '%Y%m%d%H%i%s'  ) recently_consume_time,  IFNULL(mui.total_consume_num, 0) total_consume_num,  IFNULL(mui.total_consume_amount, 0) total_consume_amount,  (  CASE  WHEN u.nick_name IS NULL THEN  '会员'  WHEN u.nick_name = '' THEN  '会员'  ELSE  u.nick_name  END  ) AS 'nickname',  u.sex,  u.head_image_url,  u.province,  u.city,  u.country
FROM  merchant_member_info mui
INNER JOIN (  SELECT  id  FROM  merchant_member_info  WHERE  merchant_id = '商户ID'  ORDER BY  recently_consume_time DESC  LIMIT 9000,  10
) AS tmp ON tmp.id = mui.id
LEFT JOIN member_info u ON mui.member_id = u.id

结尾

如果觉得对你有帮助,可以多多评论,多多点赞哦,谢谢。

我的天!!线上千万级大表排序,如何优化?相关推荐

  1. MySQL线上优化_线上MySQL千万级大表,如何优化?

    前段时间应急群有客服反馈,会员管理功能无法按到店时间.到店次数.消费金额进行排序.经过排查发现是 SQL 执行效率低,并且索引效率低下. 图片来自 Pexels 应急问题 商户反馈会员管理功能无法按到 ...

  2. 如何优化MySQL千万级大表

    很好的一篇博客,转载 如何优化MySQL千万级大表 原文链接::https://blog.csdn.net/yangjianrong1985/article/details/102675334 千万级 ...

  3. 来个硬货——长文解读:基于业务场景的MySQL千万级大表优化

    千万级大表如何优化,这是一个很有技术含量的问题,通常我们的直觉思维都会跳转到拆分或者数据分区,在此我想做一些补充和梳理,想和大家做一些这方面的经验总结,也欢迎大家提出建议. 从一开始脑海里开始也是火光 ...

  4. MySQL千万级大表优化解决方案

    MySQL千万级大表优化解决方案 参考文章: (1)MySQL千万级大表优化解决方案 (2)https://www.cnblogs.com/yliucnblogs/p/10096530.html 备忘 ...

  5. 详记一次MySQL千万级大表优化过程!

    来自:知乎,作者:互联网编程 链接:https://www.zhihu.com/question/19719997/answer/549041957 问题概述 使用阿里云rds for MySQL数据 ...

  6. 分享:详记一次MySQL千万级大表优化过程!

    问题概述 使用阿里云rds for MySQL数据库(就是MySQL5.6版本),有个用户上网记录表6个月的数据量近2000万,保留最近一年的数据量达到4000万,查询速度极慢,日常卡死.严重影响业务 ...

  7. 千万级大表如何更快速的创建索引_分享一份生产环境mysql数据库大表归档方案,值得收藏...

    概述 分享下最近做的一个mysql大表归档方案,仅供参考. 整体思路 一.明确哪些大表需做归档 1.数据库表概要信息统计 SELECTt1.table_schema,t1.table_name,`EN ...

  8. [生产库实战] 如何使用触发器对生产库上亿级大表进行实时同步

    触发器迁移数据和Oracle 物化视图(MV)的原理相同,通过在源表创建Trigger,记录源表的DML操作日志,然后通过存储过程同步DML受影响的记录,达到目标表和源表数据一致的效果.此方法只是对P ...

  9. 一次 MySQL 千万级大表的优化过程

    作者:赵客缦胡缨v吴钩霜雪明 https://www.jianshu.com/p/336f682e4b91 概述 使用阿里云rds for MySQL数据库(就是MySQL5.6版本),有个用户上网记 ...

  10. mysql千万级大表在线添加索引

    #怎样向有大量数据的表中添加索引 文章目录 前言 一.使用步骤 总结 前言 在日常开发过程中我们可能会遇见这种场景,就是为了优化查询我们需要对某张表中的某个字段添加索引,但表中存在大量数据,而且正式库 ...

最新文章

  1. LTE PUCCH Format1
  2. php 爬虫_Scrapy 爬虫完整案例-基础篇
  3. python百度百科怎么读-python英文怎么读
  4. 关于jboss在jdk6下webservice不正常问题的解决
  5. javascript常用判断写法
  6. Leetcode: Counting Bits
  7. Android 最新左右可见上下页的banner实现demo
  8. logstash收集java日志,多行合并成一行
  9. HDU 1698 Just a Hook (线段树区间修改+区间查询)
  10. WebSite设置首页或是加入收藏夹功能
  11. 三星复印机载体初始化步骤_三星复印机的使用方法
  12. 思科 Spanning Tree Protocol(STP)生成树
  13. Linux Mint 21编译Android kernel,遇到 multiple definition of `yylloc‘ 的错误解决
  14. 基于微信小程序的游泳馆管理系统设计与实现-计算机毕业设计源码+LW文档
  15. mac 给 iPhone 充电一直闪跳
  16. HTML怎么做出菱形框架,css3怎么实现菱形渐变?
  17. HSC32C1调试记录
  18. RT-Thread:让W25Q128、U盘、SD卡同时搭载文件系统
  19. 满足4G/5G基站覆盖测试、频谱扫描和清频测试功能的扫频仪 TFN FGT系列扫频仪
  20. git入门(msysgit图文安装)

热门文章

  1. spring之ControllerAdvice注解
  2. 关于Apache与Nginx的优势比较
  3. 「leetcode」349. 两个数组的交集:哈希值太大了,还是得用set
  4. git 如何忽略掉指定目录
  5. poj Washing Clothes挺好的一道01背包
  6. 如何在苹果MacBook Pro上打开和使用Touch Bar Zoom?
  7. (五)ThinkPHP实践之Session驱动-TTLSA
  8. 【vuejs面试题】务必熟知的vuejs面试题「务必收藏」
  9. [转]PostgreSQL源码结构
  10. 2013年云计算发展展望:混合云即将起飞