| 
                        副标题[/!--empirenews.page--]
                            
最近通过一个日志表做排行的时候发现特别卡,最后问题得到了解决,梳理一些索引和MySQL执行过程的经验,但是最后还是有5个谜题没解开,希望大家帮忙解答下 
主要包含如下知识点 
    - 用数据说话证明慢日志的扫描行数到底是如何统计出来的
 
    - 从 group by 执行原理找出优化方案
 
    - 排序的实现细节
 
    - gdb 源码调试
 
 
背景 
需要分别统计本月、本周被访问的文章的 TOP10。日志表如下 
- CREATE TABLE `article_rank` (  
 -   `id` int(11) unsigned NOT NULL AUTO_INCREMENT,  
 -   `aid` int(11) unsigned NOT NULL,  
 -   `pv` int(11) unsigned NOT NULL DEFAULT '1',  
 -   `day` int(11) NOT NULL COMMENT '日期 例如 20171016',  
 -   PRIMARY KEY (`id`),  
 -   KEY `idx_day_aid_pv` (`day`,`aid`,`pv`),  
 -   KEY `idx_aid_day_pv` (`aid`,`day`,`pv`)  
 - ) ENGINE=InnoDB DEFAULT CHARSET=utf8  
 
  
准备工作 
为了能够清晰的验证自己的一些猜想,在虚拟机里安装了一个 debug 版的 mysql,然后开启了慢日志收集,用于统计扫描行数 
安装 
    - 下载源码
 
    - 编译安装
 
    - 创建 mysql 用户
 
    - 初始化数据库
 
    - 初始化 mysql 配置文件
 
    - 修改密码
 
 
如果你兴趣,具体可以参考我的博客,一步步安装 https://mengkang.net/1335.html 
开启慢日志 
编辑配置文件,在[mysqld]块下添加 
- slow_query_log=1  
 - slow_query_log_file=xxx  
 - long_query_time=0  
 - log_queries_not_using_indexes=1  
 
  
性能分析 
发现问题 
假如我需要查询2018-12-20 ~ 2018-12-24这5天浏览量最大的10篇文章的 sql 如下,首先使用explain看下分析结果 
- 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;  
 - +----+-------------+--------------+------------+-------+-------------------------------+----------------+---------+------+--------+----------+-----------------------------------------------------------+ 
 -  
 - | id | select_type | table        | partitions | type  | possible_keys                 | key            | key_len | ref  | rows   | filtered | Extra                                                | 
 -  
 - +----+-------------+--------------+------------+-------+-------------------------------+----------------+---------+------+--------+----------+-----------------------------------------------------------+ 
 -  
 - |  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 | 
 -  
 - +----+-------------+--------------+------------+-------+-------------------------------+----------------+---------+------+--------+----------+-----------------------------------------------------------+ 
 
  
系统默认会走的索引是idx_day_aid_pv,根据Extra信息我们可以看到,使用idx_day_aid_pv索引的时候,会走覆盖索引,但是会使用临时表,会有排序。 
我们查看下慢日志里的记录信息 
- # Time: 2019-03-17T03:02:27.984091Z  
 - # User@Host: root[root] @ localhost []  Id:     6  
 - # Query_time: 56.959484  Lock_time: 0.000195 Rows_sent: 10  Rows_examined: 1337315  
 - SET timestamp=1552791747;  
 - 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 
                                                (编辑:52站长网) 
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! 
                     |