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

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

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

我们查询两个数据,一个是满足条件的行数,一个是group by统计之后的行数。

  1. mysql> select count(*) from article_rank where day>=20181220 and day<=20181224;  
  2. +----------+  
  3. | count(*) |  
  4. +----------+  
  5. |   785102 |  
  6. +----------+  
  7. mysql> select count(distinct aid) from article_rank where day>=20181220 and day<=20181224;  
  8. +---------------------+  
  9. | count(distinct aid) |  
  10. +---------------------+  
  11. |              552203 |  
  12. +---------------------+  

发现满足条件的总行数(785102)+group by 之后的总行数(552203)+limit 的值 = 慢日志里统计的 Rows_examined。

要解答这个问题,就必须搞清楚上面这个 sql 到底分别都是如何运行的。

执行流程分析

索引示例

为了便于理解,我按照索引的规则先模拟idx_day_aid_pv索引的一小部分数据

因为索引idx_day_aid_pv最左列是day,所以当我们需要查找20181220~20181224之间的文章的pv总和的时候,我们需要遍历20181220~20181224这段数据的索引。

  1. 查看 optimizer trace 信息  
  2. # 开启 optimizer_trace  
  3. set optimizer_trace='enabled=on';  
  4. # 执行 sql   
  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;  
  6. # 查看 trace 信息  
  7. select trace from `information_schema`.`optimizer_trace`G;  

摘取里面最后的执行结果如下

  1. {  
  2.   "join_execution": {  
  3.     "select#": 1,  
  4.     "steps": [  
  5.       {  
  6.         "creating_tmp_table": {  
  7.           "tmp_table_info": {  
  8.             "table": "intermediate_tmp_table",  
  9.             "row_length": 20,  
  10.             "key_length": 4,  
  11.             "unique_constraint": false,  
  12.             "location": "memory (heap)",  
  13.             "row_limit_estimate": 838860  
  14.           }  
  15.         }  
  16.       },  
  17.       {  
  18.         "converting_tmp_table_to_ondisk": {  
  19.           "cause": "memory_table_size_exceeded",  
  20.           "tmp_table_info": {  
  21.             "table": "intermediate_tmp_table",  
  22.             "row_length": 20,  
  23.             "key_length": 4,  
  24.             "unique_constraint": false,  
  25.             "location": "disk (InnoDB)",  
  26.             "record_format": "fixed"  
  27.           }  
  28.         }  
  29.       },  
  30.       {  
  31.         "filesort_information": [  
  32.           {  
  33.             "direction": "desc",  
  34.             "table": "intermediate_tmp_table",  
  35.             "field": "num"  
  36.           }  
  37.         ],  
  38.         "filesort_priority_queue_optimization": {  
  39.           "limit": 10,  
  40.           "rows_estimate": 1057,  
  41.           "row_size": 36,  
  42.           "memory_available": 262144,  
  43.           "chosen": true  
  44.         },  
  45.         "filesort_execution": [  
  46.         ],  
  47.         "filesort_summary": {  
  48.           "rows": 11,  
  49.           "examined_rows": 552203,  
  50.           "number_of_tmp_files": 0,  
  51.           "sort_buffer_size": 488,  
  52.           "sort_mode": "<sort_key, additional_fields>"  
  53.         }  
  54.       }  
  55.     ]  
  56.   }  
  57. }  

分析临时表字段

mysql gdb 调试更多细节 https://mengkang.net/1336.html

(编辑:东莞站长网)

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

热点阅读