加入收藏 | 设为首页 | 会员中心 | 我要投稿 宁德站长网 (https://www.0593zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

一次Group By+Order By性能优化分析

发布时间:2019-03-20 17:05:55 所属栏目:MySql教程 来源:周梦康
导读:副标题#e# 最近通过一个日志表做排行的时候发现特别卡,最后问题得到了解决,梳理一些索引和MySQL执行过程的经验,但是最后还是有5个谜题没解开,希望大家帮忙解答下 主要包含如下知识点 用数据说话证明慢日志的扫描行数到底是如何统计出来的 从 group by
副标题[/!--empirenews.page--]

 一次Group By+Order By性能优化分析

最近通过一个日志表做排行的时候发现特别卡,最后问题得到了解决,梳理一些索引和MySQL执行过程的经验,但是最后还是有5个谜题没解开,希望大家帮忙解答下

主要包含如下知识点

  • 用数据说话证明慢日志的扫描行数到底是如何统计出来的
  • 从 group by 执行原理找出优化方案
  • 排序的实现细节
  • gdb 源码调试

背景

需要分别统计本月、本周被访问的文章的 TOP10。日志表如下

  1. CREATE TABLE `article_rank` (  
  2.   `id` int(11) unsigned NOT NULL AUTO_INCREMENT,  
  3.   `aid` int(11) unsigned NOT NULL,  
  4.   `pv` int(11) unsigned NOT NULL DEFAULT '1',  
  5.   `day` int(11) NOT NULL COMMENT '日期 例如 20171016',  
  6.   PRIMARY KEY (`id`),  
  7.   KEY `idx_day_aid_pv` (`day`,`aid`,`pv`),  
  8.   KEY `idx_aid_day_pv` (`aid`,`day`,`pv`)  
  9. ) ENGINE=InnoDB DEFAULT CHARSET=utf8  

准备工作

为了能够清晰的验证自己的一些猜想,在虚拟机里安装了一个 debug 版的 mysql,然后开启了慢日志收集,用于统计扫描行数

安装

  • 下载源码
  • 编译安装
  • 创建 mysql 用户
  • 初始化数据库
  • 初始化 mysql 配置文件
  • 修改密码

如果你兴趣,具体可以参考我的博客,一步步安装 https://mengkang.net/1335.html

开启慢日志

编辑配置文件,在[mysqld]块下添加

  1. slow_query_log=1  
  2. slow_query_log_file=xxx  
  3. long_query_time=0  
  4. log_queries_not_using_indexes=1  

性能分析

发现问题

假如我需要查询2018-12-20 ~ 2018-12-24这5天浏览量最大的10篇文章的 sql 如下,首先使用explain看下分析结果

  1. mysql> explain select aid,sum(pv) as num from article_rank where day>=20181220 and day<=20181224 group by aid order by num desc limit 10;  
  2. +----+-------------+--------------+------------+-------+-------------------------------+----------------+---------+------+--------+----------+-----------------------------------------------------------+ 
  3.  
  4. | id | select_type | table        | partitions | type  | possible_keys                 | key            | key_len | ref  | rows   | filtered | Extra                                                | 
  5.  
  6. +----+-------------+--------------+------------+-------+-------------------------------+----------------+---------+------+--------+----------+-----------------------------------------------------------+ 
  7.  
  8. |  1 | SIMPLE      | article_rank | NULL       | range | idx_day_aid_pv,idx_aid_day_pv | idx_day_aid_pv | 4       | NULL | 404607 |   100.00 | Using where; Using index; Using temporary; Using filesort | 
  9.  
  10. +----+-------------+--------------+------------+-------+-------------------------------+----------------+---------+------+--------+----------+-----------------------------------------------------------+ 

系统默认会走的索引是idx_day_aid_pv,根据Extra信息我们可以看到,使用idx_day_aid_pv索引的时候,会走覆盖索引,但是会使用临时表,会有排序。

我们查看下慢日志里的记录信息

  1. # Time: 2019-03-17T03:02:27.984091Z  
  2. # User@Host: root[root] @ localhost []  Id:     6  
  3. # Query_time: 56.959484  Lock_time: 0.000195 Rows_sent: 10  Rows_examined: 1337315  
  4. SET timestamp=1552791747;  
  5. select aid,sum(pv) as num from article_rank where day>=20181220 and day<=20181224 group by aid order by num desc limit 10;  

为什么扫描行数是 1337315

(编辑:宁德站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读