加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

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

发布时间:2019-03-20 08:48:12 所属栏目:编程 来源:周梦康
导读:最近通过一个日记表做排行的时辰发明出格卡,最后题目获得了办理,梳理一些索引和MySQL执行进程的履历,可是最后照旧有5个谜题没解开,但愿各人资助解答下 首要包括如下常识点 用数据措辞证明慢日记的扫描行数到底是怎样统计出来的 从 group by 执行道理找

The SUM() and AVG() functions return a DECIMAL value for exact-value arguments (integer or DECIMAL), and a DOUBLE value for approximate-value arguments (FLOAT or DOUBLE). (Before MySQL 5.0.3, SUM() and AVG() return DOUBLE for all numeric arguments.)

可是通过我们上面打印信息可以看到两个字段的长度加起来是19,而optimizer_trace里的tmp_table_info.reclength是20。通过其他尝试也发明table->s->reclength的长度就是table->field数组内里全部字段的字段长度和再加1。

总结执行流程

  1. 实行在堆上行使memory的内存姑且表来存放group by的数据,发明内存不足;
  2. 建设一张姑且表,姑且表上有两个字段,aid和num字段(sum(pv) as num);
  3. 从索引idx_day_aid_pv中取出1行,插入姑且表。插入法则是假如aid不存在则直接插入,假如存在,则把pv的值累加在num上;
  4. 轮回遍历索引idx_day_aid_pv上20181220~20181224之间的全部行,执行步调3;
  5. 对姑且表按照num的值做优先行列排序;
  6. 取出最后留在堆(优先行列的堆)内里的10行数据,作为功效集直接返回,不必要再回表;

增补声名优先行列排序执行步调说明:

  1. 在姑且表(未排序)中取出前 10 行,把个中的num和aid作为10个元素组成一个小顶堆,也就是最小的 num 在堆顶。
  2. 取下一行,按照 num 的值和堆顶值作较量,假如该字大于堆顶的值,则替代掉。然后将新的堆做堆排序。
  3. 一再步调2直到第 552203 行较量完成。

优化

方案1 行使 idx_aid_day_pv 索引

  1. # Query_time: 4.406927  Lock_time: 0.000200 Rows_sent: 10  Rows_examined: 1337315  
  2. SET timestamp=1552791804;  
  3. select aid,sum(pv) as num from article_rank force index(idx_aid_day_pv) where day>=20181220 and day<=20181224 group by aid order by num desc limit 10;  

扫描行数都是1337315,为什么执行耗损的时刻上快了12倍呢?

索引示例

为了便于领略,,同样我也凭证索引的法则先模仿idx_aid_day_pv索引的一小部门数据

group by 不必要姑且表的环境

为什么机能上比 SQL1 高了,许多呢,缘故起因之一是idx_aid_day_pv索引上aid是确定有序的,那么执行group by的时辰,则不会建设姑且表,排序的时辰才必要姑且表。假如印证这一点呢,我们通过下面的执行打算就能看到

行使idx_day_aid_pv索引的结果:

  1. mysql> explain select aid,sum(pv) as num from article_rank force index(idx_day_aid_pv) where day>=20181220 and day<=20181224 group by aid order by null limit 10; 
  2.  
  3. +----+-------------+--------------+------------+-------+-------------------------------+----------------+---------+------+--------+----------+-------------------------------------------+ 
  4.  
  5. | id | select_type | table        | partitions | type  | possible_keys                 | key            | key_len | ref  | rows   | filtered | Extra                                     | 
  6.  
  7. +----+-------------+--------------+------------+-------+-------------------------------+----------------+---------+------+--------+----------+-------------------------------------------+ 
  8.  
  9. |  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 | 
  10.  
  11. +----+-------------+--------------+------------+-------+-------------------------------+----------------+---------+------+--------+----------+-------------------------------------------+  

留意我上面行使了order by null暗示逼迫对group by的功效不做排序。假如不加order by null,上面的 sql 则会呈现Using filesort

(编辑:湖南网)

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

热点阅读