自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

一次Group By+Order By性能優(yōu)化分析

數(shù)據(jù)庫 MySQL
最近通過一個日志表做排行的時候發(fā)現(xiàn)特別卡,問題得到了解決,梳理一些索引和MySQL執(zhí)行過程的經(jīng)驗,但是還是有5個謎題沒解開,希望大家?guī)兔獯鹣隆?/div>

 

最近通過一個日志表做排行的時候發(fā)現(xiàn)特別卡,問題得到了解決,梳理一些索引和MySQL執(zhí)行過程的經(jīng)驗,但是還是有5個謎題沒解開,希望大家?guī)兔獯鹣?/p>

主要包含如下知識點

  • 用數(shù)據(jù)說話證明慢日志的掃描行數(shù)到底是如何統(tǒng)計出來的
  • 從 group by 執(zhí)行原理找出優(yōu)化方案
  • 排序的實現(xiàn)細節(jié)
  • gdb 源碼調(diào)試

背景

需要分別統(tǒng)計本月、本周被訪問的文章的 前10。日志表如下 

  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  

準(zhǔn)備工作

為了能夠清晰的驗證自己的一些猜想,在虛擬機里安裝了一個 debug 版的 mysql,然后開啟了慢日志收集,用于統(tǒng)計掃描行數(shù)

安裝

  • 下載源碼
  • 編譯安裝
  • 創(chuàng)建 mysql 用戶
  • 初始化數(shù)據(jù)庫
  • 初始化 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  

性能分析

發(fā)現(xiàn)問題

假如我需要查詢2018-12-20 ~ 2018-12-24這5天瀏覽量多的10篇文章的 sql 如下,首先使用explain看下分析結(jié)果 

  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. +----+-------------+--------------+------------+-------+-------------------------------+----------------+---------+------+--------+----------+-----------------------------------------------------------+ 

 系統(tǒng)默認會走的索引是idx_day_aid_pv,根據(jù)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;  

為什么掃描行數(shù)是 1337315

我們查詢兩個數(shù)據(jù),一個是滿足條件的行數(shù),一個是group by統(tǒng)計之后的行數(shù)。 

  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. +---------------------+  

發(fā)現(xiàn)滿足條件的總行數(shù)(785102)+group by 之后的總行數(shù)(552203)+limit 的值 = 慢日志里統(tǒng)計的 Rows_examined。

要解答這個問題,就必須搞清楚上面這個 sql 到底分別都是如何運行的。

執(zhí)行流程分析

索引示例

為了便于理解,我按照索引的規(guī)則先模擬idx_day_aid_pv索引的一小部分數(shù)據(jù)

day aid pv id
20181220 1 23 1234
20181220 3 2 1231
20181220 4 1 1212
20181220 7 2 1221
20181221 1 5 1257
20181221 10 1 1251
20181221 11 8 1258

因為索引idx_day_aid_pv最左列是day,所以當(dāng)我們需要查找20181220~20181224之間的文章的pv總和的時候,我們需要遍歷20181220~20181224這段數(shù)據(jù)的索引。 

  1. 查看 optimizer trace 信息  
  2. # 開啟 optimizer_trace  
  3. set optimizer_trace='enabled=on' 
  4. # 執(zhí)行 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;  

摘取里面的執(zhí)行結(jié)果如下 

  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 調(diào)試更多細節(jié) https://mengkang.net/1336.html

通過gdb調(diào)試確認臨時表上的字段是aid和num 

  1. Breakpoint 1, trace_tmp_table (trace=0x7eff94003088table=0x7eff94937200) at /root/newdb/mysql-server/sql/sql_tmp_table.cc:2306  
  2. warning: Source file is more recent than executable.  
  3. 2306      trace_tmp.add("row_length",table->s->reclength).  
  4. (gdb) p table->s->reclength  
  5. $1 = 20  
  6. (gdb) p table->s->fields  
  7. $22 = 2  
  8. (gdb) p (*(table->field+0))->field_name  
  9. $3 = 0x7eff94010b0c "aid"  
  10. (gdb) p (*(table->field+1))->field_name  
  11. $4 = 0x7eff94007518 "num"  
  12. (gdb) p (*(table->field+0))->row_pack_length()  
  13. $5 = 4  
  14. (gdb) p (*(table->field+1))->row_pack_length()  
  15. $6 = 15  
  16. (gdb) p (*(table->field+0))->type()  
  17. $7 = MYSQL_TYPE_LONG  
  18. (gdb) p (*(table->field+1))->type()  
  19. $8 = MYSQL_TYPE_NEWDECIMAL  
  20. (gdb)  

通過上面的打印,確認了字段類型,一個aid是MYSQL_TYPE_LONG,占4字節(jié),num是MYSQL_TYPE_NEWDECIMAL,占15字節(jié)。

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。通過其他實驗也發(fā)現(xiàn)table->s->reclength的長度就是table->field數(shù)組里面所有字段的字段長度和再加1。

總結(jié)執(zhí)行流程

  1. 嘗試在堆上使用memory的內(nèi)存臨時表來存放group by的數(shù)據(jù),發(fā)現(xiàn)內(nèi)存不夠;
  2. 創(chuàng)建一張臨時表,臨時表上有兩個字段,aid和num字段(sum(pv) as num);
  3. 從索引idx_day_aid_pv中取出1行,插入臨時表。插入規(guī)則是如果aid不存在則直接插入,如果存在,則把pv的值累加在num上;
  4. 循環(huán)遍歷索引idx_day_aid_pv上20181220~20181224之間的所有行,執(zhí)行步驟3;
  5. 對臨時表根據(jù)num的值做優(yōu)先隊列排序;
  6. 取出留在堆(優(yōu)先隊列的堆)里面的10行數(shù)據(jù),作為結(jié)果集直接返回,不需要再回表;

補充說明優(yōu)先隊列排序執(zhí)行步驟分析:

  1. 在臨時表(未排序)中取出前 10 行,把其中的num和aid作為10個元素構(gòu)成一個小頂堆,也就是最小的 num 在堆頂。
  2. 取下一行,根據(jù) num 的值和堆頂值作比較,如果該字大于堆頂?shù)闹担瑒t替換掉。然后將新的堆做堆排序。
  3. 重復(fù)步驟2直到第 552203 行比較完成。

優(yōu)化

方案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;  

掃描行數(shù)都是1337315,為什么執(zhí)行消耗的時間上快了12倍呢?

索引示例

為了便于理解,同樣我也按照索引的規(guī)則先模擬idx_aid_day_pv索引的一小部分數(shù)據(jù)

aid day pv id
1 20181220 23 1234
1 20181221 5 1257
3 20181220 2 1231
3 20181222 22 1331
3 20181224 13 1431
4 20181220 1 1212
7 20181220 2 1221
10 20181221 1 1251
11 20181221 8 1258

group by 不需要臨時表的情況

為什么性能上比 SQL1 高了,很多呢,原因之一是idx_aid_day_pv索引上aid是確定有序的,那么執(zhí)行g(shù)roup by的時候,則不會創(chuàng)建臨時表,排序的時候才需要臨時表。如果印證這一點呢,我們通過下面的執(zhí)行計劃就能看到

使用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的結(jié)果不做排序。如果不加order by null,上面的 sql 則會出現(xiàn)Using filesort

使用idx_aid_day_pv索引的效果: 

  1. mysql> explain 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 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       | index | idx_day_aid_pv,idx_aid_day_pv | idx_aid_day_pv | 12      | NULL |   10 |    11.11 | Using where; Using index | 
  10.  
  11. +----+-------------+--------------+------------+-------+-------------------------------+----------------+---------+------+------+----------+--------------------------+  

查看 optimizer trace 信息 

  1. # 開啟optimizer_trace  
  2. set optimizer_trace='enabled=on' 
  3. # 執(zhí)行 sql   
  4. 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;  
  5. # 查看 trace 信息  
  6. select trace from `information_schema`.`optimizer_trace`\G;  

摘取里面的執(zhí)行結(jié)果如下 

  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": 0,  
  11.             "unique_constraint": false,  
  12.             "location": "memory (heap)",  
  13.             "row_limit_estimate": 838860  
  14.           }  
  15.         }  
  16.       },  
  17.       {  
  18.         "filesort_information": [  
  19.           {  
  20.             "direction": "desc",  
  21.             "table": "intermediate_tmp_table",  
  22.             "field": "num"  
  23.           }  
  24.         ],  
  25.         "filesort_priority_queue_optimization": {  
  26.           "limit": 10,  
  27.           "rows_estimate": 552213,  
  28.           "row_size": 24,  
  29.           "memory_available": 262144,  
  30.           "chosen": true  
  31.         },  
  32.         "filesort_execution": [  
  33.         ],  
  34.         "filesort_summary": {  
  35.           "rows": 11,  
  36.           "examined_rows": 552203,  
  37.           "number_of_tmp_files": 0,  
  38.           "sort_buffer_size": 352,  
  39.           "sort_mode": "<sort_key, rowid> 
  40.         }  
  41.       }  
  42.     ]  
  43.   }  
  44.  

執(zhí)行流程如下

      1. 創(chuàng)建一張臨時表,臨時表上有兩個字段,aid和num字段(sum(pv) as num);

      2. 讀取索引idx_aid_day_pv中的一行,然后查看是否滿足條件,如果day字段不在條件范圍內(nèi)(20181220~20181224之間),則讀取下一行;如果day字段在條件范圍內(nèi),則把pv值累加(不是             在臨時表中操作);

      3. 讀取索引idx_aid_day_pv中的下一行,如果aid與步驟1中一致且滿足條件,則pv值累加(不是在臨時表中操作)。如果aid與步驟1中不一致,則把之前的結(jié)果集寫入臨時表;

      4. 循環(huán)執(zhí)行步驟2、3,直到掃描完整個idx_aid_day_pv索引;

      5. 對臨時表根據(jù)num的值做優(yōu)先隊列排序;

      6. 根據(jù)查詢到的前10條的rowid回表(臨時表)返回結(jié)果集。

補充說明優(yōu)先隊列排序執(zhí)行步驟分析:

  1. 在臨時表(未排序)中取出前 10 行,把其中的num和rowid作為10個元素構(gòu)成一個小頂堆,也就是最小的 num 在堆頂。
  2. 取下一行,根據(jù) num 的值和堆頂值作比較,如果該字大于堆頂?shù)闹?,則替換掉。然后將新的堆做堆排序。
  3. 重復(fù)步驟2直到第 552203 行比較完成。

該方案可行性

實驗發(fā)現(xiàn),當(dāng)我增加一行20181219的數(shù)據(jù)時,雖然這行記錄不滿足我們的需求,但是掃描索引的也會讀取這行。因為我做這個實驗,只弄了20181220~201812245天的數(shù)據(jù),所以需要掃描的行數(shù)正好是全表數(shù)據(jù)行數(shù)。

那么如果該表的數(shù)據(jù)存儲的不是5天的數(shù)據(jù),而是10天的數(shù)據(jù)呢,更或者是365天的數(shù)據(jù)呢?這個方案是否還可行呢?先模擬10天的數(shù)據(jù),在現(xiàn)有時間基礎(chǔ)上往后加5天,行數(shù)與現(xiàn)在一樣785102行。 

  1. drop procedure if exists idata;  
  2. delimiter ;;  
  3. create procedure idata()  
  4. begin  
  5.   declare i int;  
  6.   declare aid int;  
  7.   declare pv int;  
  8.   declare post_day int;  
  9.   set i=1 
  10.   while(i<=785102)do  
  11.     set aid = round(rand()*500000);  
  12.     set pv = round(rand()*100);  
  13.     set post_day = 20181225 + i%5;  
  14.     insert into article_rank (`aid`,`pv`,`day`) values(aid, pv, post_day);  
  15.     set ii=i+1;  
  16.   end while;  
  17. end;;  
  18. delimiter ;  
  19. call idata();  
  20. # Query_time: 9.151270  Lock_time: 0.000508 Rows_sent: 10  Rows_examined: 2122417  
  21. SET timestamp=1552889936 
  22. 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;  

這里掃描行數(shù)2122417是因為掃描索引的時候需要遍歷整個索引,整個索引的行數(shù)就是全表行數(shù),因為我剛剛又插入了785102行。

當(dāng)我數(shù)據(jù)量翻倍之后,這里查詢時間明顯已經(jīng)翻倍。所以這個優(yōu)化方式不穩(wěn)定。

方案2 擴充臨時表空間上限大小

默認的臨時表空間大小是16MB 

  1. mysql> show global variables like '%table_size';  
  2. +---------------------+----------+  
  3. | Variable_name       | Value    |  
  4. +---------------------+----------+  
  5. | max_heap_table_size | 16777216 |  
  6. | tmp_table_size      | 16777216 |  
  7. +---------------------+----------+  

https://dev.mysql.com/doc/ref...

https://dev.mysql.com/doc/ref...

max_heap_table_size

This variable sets the maximum size to which user-created MEMORY tables are permitted to grow. The value of the variable is used to calculate MEMORY table MAX_ROWS values. Setting this variable has no effect on any existing MEMORY table, unless the table is re-created with a statement such as CREATE TABLE or altered with ALTER TABLE or TRUNCATE TABLE. A server restart also sets the maximum size of existing MEMORY tables to the global max_heap_table_size value.

tmp_table_size 

The maximum size of internal in-memory temporary tables. This variable does not apply to user-created MEMORY tables.

The actual limit is determined from whichever of the values of tmp_table_size and max_heap_table_size is smaller. If an in-memory temporary table exceeds the limit, MySQL automatically converts it to an on-disk temporary table. The internal_tmp_disk_storage_engine option defines the storage engine used for on-disk temporary tables.

也就是說這里臨時表的限制是16M,max_heap_table_size大小也受tmp_table_size大小的限制。

所以我們這里調(diào)整為32MB,然后執(zhí)行原始的SQL 

  1. set tmp_table_size=33554432 
  2. set max_heap_table_size=33554432 
  1. # Query_time: 5.910553  Lock_time: 0.000210 Rows_sent: 10  Rows_examined: 1337315  
  2. SET timestamp=1552803869 
  3. select aid,sum(pv) as num from article_rank where day>=20181220 and day<=20181224 group by aid order by num desc limit 10;  

方案3 使用 SQL_BIG_RESULT 優(yōu)化

告訴優(yōu)化器,查詢結(jié)果比較多,臨時表直接走磁盤存儲。 

  1. # Query_time: 6.144315  Lock_time: 0.000183 Rows_sent: 10  Rows_examined: 2122417  
  2. SET timestamp=1552802804 
  3. select SQL_BIG_RESULT aid,sum(pv) as num from article_rank where day>=20181220 and day<=20181224 group by aid order by num desc limit 10;  

掃描行數(shù)是 2x滿足條件的總行數(shù)(785102)+group by 之后的總行數(shù)(552203)+limit 的值。

順便值得一提的是: 當(dāng)我把數(shù)據(jù)量翻倍之后,使用該方式,查詢時間基本沒變。因為掃描的行數(shù)還是不變的。實際測試耗時6.197484

總結(jié)

方案1優(yōu)化效果不穩(wěn)定,當(dāng)總表數(shù)據(jù)量與查詢范圍的總數(shù)相同時,且不超出內(nèi)存臨時表大小限制時,性能達到更佳。當(dāng)查詢數(shù)據(jù)量占據(jù)總表數(shù)據(jù)量越大,優(yōu)化效果越不明顯;

方案2需要調(diào)整臨時表內(nèi)存的大小,可行;不過當(dāng)數(shù)據(jù)庫超過32MB時,如果使用該方式,還需要繼續(xù)提升臨時表大小;

方案3直接聲明使用磁盤來放臨時表,雖然掃描行數(shù)多了一次符合條件的總行數(shù)的掃描。但是整體響應(yīng)時間比方案2就慢了0.1秒。因為我們這里數(shù)據(jù)量比較,我覺得這個時間差還能接受。

所以對比,選擇方案3比較合適。

問題與困惑 

  1. # SQL1  
  2. select aid,sum(pv) as num from article_rank where day>=20181220 and day<=20181224 group by aid order by num desc limit 10;  
  3. # SQL2  
  4. 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;  
  1. SQL1 執(zhí)行過程中,使用的是全字段排序后不需要回表為什么總掃描行數(shù)還要加上10才對得上?
  2. SQL1 與 SQL2 group by之后得到的行數(shù)都是552203,為什么會出現(xiàn) SQL1 內(nèi)存不夠,里面還有哪些細節(jié)呢?
  3. trace 信息里的creating_tmp_table.tmp_table_info.row_limit_estimate都是838860;計算由來是臨時表的內(nèi)存限制大小16MB,而一行需要占的空間是20字節(jié),那么最多只能容納                             floor(16777216/20) = 838860行,而實際我們需要放入臨時表的行數(shù)是785102。為什么呢?
  4. SQL1 使用SQL_BIG_RESULT優(yōu)化之后,原始表需要掃描的行數(shù)會乘以2,背后邏輯是什么呢?為什么僅僅是不再嘗試往內(nèi)存臨時表里寫入這一步會相差10多倍的性能?
  5. 通過源碼看到 trace 信息里面很多掃描行數(shù)都不是實際的行數(shù),既然是實際執(zhí)行,為什么 trace 信息里不輸出真實的掃描行數(shù)和容量等呢,比如                                                                                   filesort_priority_queue_optimization.rows_estimate在SQL1中的掃描行數(shù)我通過gdb看到計算規(guī)則如附錄圖 1
  6. 有沒有工具能夠統(tǒng)計 SQL 執(zhí)行過程中的 I/O 次數(shù)? 
責(zé)任編輯:龐桂玉 來源: segmentfault
相關(guān)推薦

2015-07-17 10:04:33

MKMapView優(yōu)化

2021-01-08 13:52:15

Consul微服務(wù)服務(wù)注冊中心

2020-02-10 10:15:31

技術(shù)研發(fā)指標(biāo)

2021-01-24 11:46:26

自動化Web 優(yōu)化

2020-06-05 08:53:31

接口性能實踐

2021-10-09 10:24:08

NET爬蟲內(nèi)存

2020-08-10 11:00:02

Python優(yōu)化代碼

2020-10-19 19:45:58

MySQL數(shù)據(jù)庫優(yōu)化

2020-10-30 14:11:38

服務(wù)器SDK堆棧

2011-04-07 11:20:21

SQLServer

2021-03-12 15:08:23

服務(wù)器性能優(yōu)化

2011-09-27 10:35:44

2011-02-22 09:29:23

jQueryJavaScript

2023-11-06 07:45:42

單據(jù)圖片處理

2021-08-26 22:26:55

性能優(yōu)化技術(shù)

2018-06-26 15:58:06

數(shù)據(jù)庫MySQL索引優(yōu)化

2010-07-30 16:10:45

UPS設(shè)備燒毀故障分析

2023-11-29 12:12:24

Oceanbase數(shù)據(jù)庫

2019-01-21 11:17:13

CPU優(yōu)化定位

2022-06-08 09:55:19

Data Catal字節(jié)跳動業(yè)務(wù)系統(tǒng)
點贊
收藏

51CTO技術(shù)棧公眾號