副标题[/!--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
(编辑:晋中站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|