精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

這個 MySQL bug 99% 的人會踩坑!

運維 數據庫運維
我們知道 MySQL 是基于成本來選擇是基于全表掃描還是選擇某個索引來執行最終的執行計劃的。

 

這周收到一個 sentry 報警,如下 SQL 查詢超時了。

  1. select * from order_info where uid = 5837661 order by id asc limit 1 

執行 show create table order_info 發現這個表其實是有加索引的

  1. CREATE TABLE `order_info` ( 
  2.  
  3. `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
  4.  
  5. `uid` int(11) unsigned, 
  6.  
  7. `order_status` tinyint(3) DEFAULT NULL, 
  8.  
  9. ... 省略其它字段和索引 
  10.  
  11. PRIMARY KEY (`id`), 
  12.  
  13. KEY `idx_uid_stat` (`uid`,`order_status`), 
  14.  
  15. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 

理論上執行上述 SQL 會命中 idx_uid_stat 這個索引,但實際執行 explain 查看

  1. explain select * from order_info where uid = 5837661 order by id asc limit 1 

可以看到它的 possible_keys(此 SQL 可能涉及到的索引) 是 idx_uid_stat,但實際上(key)用的卻是全表掃描

我們知道 MySQL 是基于成本來選擇是基于全表掃描還是選擇某個索引來執行最終的執行計劃的,所以看起來是全表掃描的成本小于基于 idx_uid_stat 索引執行的成本,不過我的第一感覺很奇怪,這條 SQL 雖然是回表,但它的 limit 是 1,也就是說只選擇了滿足 uid = 5837661 中的其中一條語句,就算回表也只回一條記錄,這種成本幾乎可以忽略不計,優化器怎么會選擇全表掃描呢。

為了查看 MySQL 優化器為啥選擇了全表掃描,我打開了 optimizer_trace 來一探究竟

畫外音:在MySQL 5.6 及之后的版本中,我們可以使用 optimizer trace 功能查看優化器生成執行計劃的整個過程

使用 optimizer_trace 的具體過程如下

  1. SET optimizer_trace="enabled=on"// 打開 optimizer_trace 
  2.  
  3. SELECT * FROM order_info where uid = 5837661 order by id asc limit 1 
  4.  
  5. SELECT * FROM information_schema.OPTIMIZER_TRACE; // 查看執行計劃表 
  6.  
  7. SET optimizer_trace="enabled=off"// 關閉 optimizer_trace 

MySQL 優化器首先會計算出全表掃描的成本,然后選出該 SQL 可能涉及到的所有索引并且計算索引的成本,然后選出所有成本最小的那個來執行,來看下 optimizer trace 給出的關鍵信息

  1.  
  2. "rows_estimation": [ 
  3.  
  4.  
  5. "table""`rebate_order_info`"
  6.  
  7. "range_analysis": { 
  8.  
  9. "table_scan": { 
  10.  
  11. "rows"21155996
  12.  
  13. "cost"4.45e6 // 全表掃描成本 
  14.  
  15.  
  16. }, 
  17.  
  18. ... 
  19.  
  20. "analyzing_range_alternatives": { 
  21.  
  22. "range_scan_alternatives": [ 
  23.  
  24.  
  25. "index""idx_uid_stat"
  26.  
  27. "ranges": [ 
  28.  
  29. "5837661 <= uid <= 5837661" 
  30.  
  31. ], 
  32.  
  33. "index_dives_for_eq_ranges"true
  34.  
  35. "rowid_ordered"false
  36.  
  37. "using_mrr"false
  38.  
  39. "index_only"false
  40.  
  41. "rows"255918
  42.  
  43. "cost"307103// 使用idx_uid_stat索引的成本 
  44.  
  45. "chosen"true 
  46.  
  47.  
  48. ], 
  49.  
  50. "chosen_range_access_summary": { // 經過上面的各個成本比較后選擇的最終結果 
  51.  
  52. "range_access_plan": { 
  53.  
  54. "type""range_scan"
  55.  
  56. "index""idx_uid_stat"// 可以看到最終選擇了idx_uid_stat這個索引來執行 
  57.  
  58. "rows"255918
  59.  
  60. "ranges": [ 
  61.  
  62. "58376617 <= uid <= 58376617" 
  63.  
  64.  
  65. }, 
  66.  
  67. "rows_for_plan"255918
  68.  
  69. "cost_for_plan"307103
  70.  
  71. "chosen"true 
  72.  
  73.  
  74.  
  75. ... 

可以看到全表掃描的成本是 4.45e6,而選擇索引 idx_uid_stat 的成本是 307103,遠小于全表掃描的成本,而且從最終的選擇結果(chosen_range_access_summary)來看,確實也是選擇了 idx_uid_stat 這個索引,但為啥從 explain 看到的選擇是執行 PRIMARY 也就是全表掃描呢,難道這個執行計劃有誤?

仔細再看了一下這個執行計劃,果然發現了貓膩,執行計劃中有一個 reconsidering_access_paths_for_index_ordering 選擇引起了我的注意

  1.  
  2. "reconsidering_access_paths_for_index_ordering": { 
  3.  
  4. "clause""ORDER BY"
  5.  
  6. "index_order_summary": { 
  7.  
  8. "table""`rebate_order_info`"
  9.  
  10. "index_provides_order"true
  11.  
  12. "order_direction""asc"
  13.  
  14. "index""PRIMARY"// 可以看到選擇了主鍵索引 
  15.  
  16. "plan_changed"true
  17.  
  18. "access_type""index_scan" 
  19.  
  20.  
  21.  

這個選擇表示由于排序的原因再進行了一次索引選擇優化,由于我們的 SQL 使用了 id 排序(order by id asc limit 1),優化器最終選擇了 PRIMARY 也就是全表掃描來執行,也就是說這個選擇會無視之前的基于索引成本的選擇,為什么會有這樣的一個選項呢,主要原因如下:

  1. The short explanation is that the optimizer thinks — or should I say hopes — that scanning the whole table (which is already sorted by the id field) will find the limited rows quick enough, and that this will avoid a sort operation. So by trying to avoid a sort, the optimizer ends-up losing time scanning the table. 

從這段解釋可以看出主要原因是由于我們使用了 order by id asc 這種基于 id 的排序寫法,優化器認為排序是個昂貴的操作,所以為了避免排序,并且它 認為 limit n 的 n 如果很小的話即使使用全表掃描也能很快執行完,所以它選擇了全表掃描,也就避免了 id 的排序(全表掃描其實就是基于 id 主鍵的聚簇索引的掃描,本身就是基于 id 排好序的)

如果這個選擇是對的那也罷了,然而實際上這個優化卻是有 bug 的!實際選擇 idx_uid_stat 執行會快得多(只要 28 ms)!網上有不少人反饋這個問題,而且出現這個問題基本只與 SQL 中出現 order by id asc limit n 這種寫法有關,如果 n 比較小很大概率會走全表掃描,如果 n 比較大則會選擇正確的索引。

這個 bug 最早追溯到 2014 年,不少人都呼吁官方及時修正這個bug,可能是實現比較困難,直到 MySQL 5.7,8.0 都還沒解決,所以在官方修復前我們要盡量避免這種寫法,如果一定要用這種寫法,怎么辦呢,主要有兩種方案

使用 force index 來強制使用指定的索引,如下:

  1. select * from order_info force index(idx_uid_stat) where uid = 5837661 order by id asc limit 1 

這種寫法雖然可以,但不夠優雅,如果這個索引被廢棄了咋辦?于是有了第二種比較優雅的方案

使用 order by (id+0) 方案,如下

  1. select * from order_info where uid = 5837661 order by (id+0) asc limit 1 

這種方案也可以讓優化器選擇正確的索引,更推薦!為什么這個 trick 可以呢,因為此 SQL 雖然是按 id 排序的,但在 id 上作了加法這樣耗時的操作(雖然只是加個無用的 0,但足以騙過優化器),優化器認為此時基于全表掃描會更耗性能,于是會選擇基于成本大小的方式來選擇索引

巨人的肩膀

mysql 優化器 bug http://4zsw5.cn/L1zEi

 

責任編輯:張燕妮 來源: 碼海
相關推薦

2021-10-15 06:49:37

MySQL

2025-10-22 08:55:16

2025-04-14 09:31:03

2024-10-08 08:14:08

用戶生命周期分析服務

2022-07-15 08:20:54

Java基礎知識

2020-04-02 14:33:42

MySQLBUG解決方案

2020-07-20 09:40:49

MySQLBUG數據庫

2021-12-28 08:17:41

循環 forgo

2022-10-31 18:38:24

MySQL數據訂單表

2024-09-29 09:27:10

2024-09-27 09:31:25

2025-05-27 01:55:00

MySQL數據庫工具鏈

2025-11-18 01:33:00

2025-04-29 08:30:00

迭代器失效C++編程

2024-11-26 08:20:53

程序數據歸檔庫

2018-01-10 13:40:03

數據庫MySQL表設計

2025-04-03 12:30:00

C 語言隱式類型轉換代碼

2023-01-18 23:20:25

編程開發

2020-09-15 08:46:26

Kubernetes探針服務端

2022-07-26 09:34:23

監控系統
點贊
收藏

51CTO技術棧公眾號

国产精品对白交换视频| 亚洲第一精品影视| 日韩视频在线永久播放| 国产精品专区在线| 国产综合视频一区二区三区免费| 亚洲瘦老头同性70tv| 欧美主播一区二区三区| 国产对白在线播放| 成人av一区二区三区在线观看 | 成人妇女淫片aaaa视频| 91porn在线视频| 蜜桃一区二区三区| 日韩一级免费一区| 成年人视频在线免费| www.欧美日本韩国| 久久久99精品免费观看| 超碰97人人人人人蜜桃| 国产三级理论片| 中日韩男男gay无套| 久久精品国产91精品亚洲| 无码精品一区二区三区在线播放 | 国产精品毛片视频| 欧美日韩国产欧美日美国产精品| 欧美日韩精品综合| 亚洲第一页视频| 久久精品系列| 久久人人爽人人| 99鲁鲁精品一区二区三区| 久久av导航| 亚洲第一网站免费视频| 1314成人网| 国产黄色一区| 在线观看免费一区| 99热在线这里只有精品| 丰乳肥臀在线| 亚洲免费看黄网站| 在线观看一区欧美| 91涩漫在线观看| 久久精品视频在线看| 精品久久久久久综合日本| www.天天干.com| 国内精品伊人久久久久av影院| 久久伊人91精品综合网站| 国产伦精品一区二区三区视频女| 国产精品亚洲一区二区三区在线观看| 久久久亚洲高清| 国内一区二区在线视频观看| 亚洲h视频在线观看| 国产在线乱码一区二区三区| 国产在线999| 中文字幕在线2019| 日韩av一区二| 国产精品久久视频| 亚洲一区在线观| 麻豆国产精品视频| 91精品国产综合久久香蕉的用户体验 | 亚洲欧美综合另类| 宅男噜噜噜66国产日韩在线观看| 国产小视频91| 国产美女免费网站| 蜜桃成人av| 9i在线看片成人免费| 国产亚洲综合av| 久久天天狠狠| 免费黄色在线视频网站| 久久精品一级爱片| 午夜午夜精品一区二区三区文| 最近国语视频在线观看免费播放| 欧美.日韩.国产.一区.二区| 免费91在线视频| 动漫性做爰视频| 欧美精品啪啪| 欧美怡春院一区二区三区| 日韩黄色一级视频| 久久精品久久综合| 亚洲最大的av网站| 天堂网在线资源| 久久久99精品免费观看不卡| 亚洲日本一区二区三区在线不卡| 色婷婷中文字幕| 久久亚洲精品国产精品紫薇| 麻豆av一区二区三区久久| 国产永久免费高清在线观看 | 国产一区二区在线播放| 国产视频手机在线观看| 成人黄页在线观看| 日本不卡一区二区三区在线观看| www.激情五月| 99精品1区2区| 一本一生久久a久久精品综合蜜| 午夜在线观看视频18| 国产农村妇女毛片精品久久麻豆 | 亚洲精品高清在线| 日本欧美视频在线观看| 一区二区视频免费完整版观看| 亚洲sss视频在线视频| 精品久久久久久久无码| 成人av在线播放| 亚洲国产欧美自拍| 成人三级视频在线观看| 激情文学一区| 国产精品揄拍一区二区| 亚洲国产视频一区二区三区| 久久影院午夜论| 日本老太婆做爰视频| xxx欧美xxx| 日韩美女视频在线| 欧美性受xxxx黑人| 日韩一级在线| 91免费版黄色| 麻豆视频在线| 色999日韩国产欧美一区二区| 东京热加勒比无码少妇| 国产精品欧美一区二区三区不卡 | 亚洲性图一区二区| 久久男人av| 美女视频久久黄| 精品国产乱子伦| 9色porny自拍视频一区二区| 久久久无码中文字幕久...| 欧美va在线观看| 亚洲福利在线播放| 久久成人在线观看| 精品一区二区三区av| 日本欧美精品久久久| 国产区美女在线| 欧美高清视频一二三区 | 久久久精品免费视频| 国产欧美一区二区三区在线看蜜臂| 免费在线亚洲欧美| 91一区二区三区| 麻豆91在线| 欧美日韩中文另类| 性高潮久久久久久久| 亚洲精品影视| 国产精品一区二区av| 日本大片在线播放| 欧美一区二区三区视频在线| 男人av资源站| 国产一区二区在线看| 国产又粗又硬又长| 在线日韩三级| 久久精品国产清自在天天线 | 久久精品无码一区| 美女91精品| 精品无人区一区二区三区竹菊| 国模吧精品人体gogo| 欧美日韩中文字幕综合视频 | 国产综合久久久久久久久久久久| 亚洲xxxx在线| 欧美家庭影院| 日韩精品一区二区三区在线| 福利所第一导航| 国产精品影视网| 成人毛片100部免费看| 久久久久毛片免费观看| 欧美日韩高清在线观看| 亚洲老妇色熟女老太| 亚洲成人在线免费| 北岛玲一区二区| 久久久久国产精品午夜一区| 欧美日韩在线一区二区三区| 日韩欧美一区二区三区在线观看| 日韩无一区二区| 欧美日韩国产精品一区二区三区| 爽好多水快深点欧美视频| 欧美在线日韩精品| 久久久久久久性潮| 久热精品视频在线免费观看 | 在线观看免费黄色| 有码一区二区三区| 黄色免费看视频| 久久中文在线| 99re99热| 久本草在线中文字幕亚洲| 欧美专区国产专区| 免费不卡视频| 亚洲福利视频网| 超碰在线免费97| 一区二区欧美视频| 欧美做受xxxxxⅹ性视频| 另类专区欧美蜜桃臀第一页| 91免费国产精品| 小嫩嫩12欧美| 91中文字幕一区| 亚洲涩涩在线| 久久夜色精品国产欧美乱| 亚洲aⅴ在线观看| 欧美视频中文一区二区三区在线观看 | 日韩妆和欧美的一区二区| 黄色成人小视频| 久久久久久久久久婷婷| 番号在线播放| 精品国产污网站| 黄色网址中文字幕| 亚洲午夜精品网| 色欲av无码一区二区三区| 国产一区视频导航| 男女av免费观看| 国产精品九九| 亚洲精品在线观看免费| 欧美韩一区二区| 91麻豆国产语对白在线观看| 色多多在线观看| 欧美成人午夜激情在线| 国产三级电影在线观看| 亚洲国产高清自拍| 97人妻一区二区精品免费视频| 国产精品美女久久久久久久久久久| 50路60路老熟妇啪啪| 欧美精品激情| 综合国产精品久久久| 亚洲精品中文字幕99999| 91中文字精品一区二区| 福利视频亚洲| 国产91精品最新在线播放| 女人天堂av在线播放| 日韩有码视频在线| 韩国中文字幕2020精品| 欧美大片日本大片免费观看| 一区二区视频在线免费观看| 欧美视频国产精品| 国产在线视频二区| 亚洲精品老司机| 国产麻豆a毛片| 欧美激情中文不卡| av黄色在线免费观看| 久久免费国产精品| 亚洲av无码成人精品国产| 国产91精品露脸国语对白| www.成人黄色| 久久99精品一区二区三区 | 在线免费av导航| 在线精品高清中文字幕| 噜噜噜在线观看播放视频| 亚洲精品电影网| 手机看片国产1024| 亚洲国产精品人久久电影| 国内精品国产成人国产三级| 欧美喷潮久久久xxxxx| 羞羞色院91蜜桃| 色88888久久久久久影院野外| 国产午夜精品理论片| 国产精品欧美久久久久一区二区| 天堂在线精品视频| 国产在线看一区| 91网址在线观看精品| 精品在线免费观看| 一级淫片在线观看| 国产精品一二二区| 亚洲成年人av| 99国内精品久久| 亚洲熟妇无码av| 国产偷国产偷亚洲高清人白洁 | 蜜桃传媒一区二区三区| 欧美精品一线| 久久这里只有精品23| 一区二区福利| 六月丁香婷婷在线| 蜜桃视频免费观看一区| 亚洲18在线看污www麻豆| 国产精品一区免费在线观看| 性xxxxxxxxx| 91在线观看一区二区| 国产伦精品一区二区三区视频女| 懂色一区二区三区免费观看| 国产成人精品无码片区在线| 久久先锋影音av鲁色资源| 亚洲高潮女人毛茸茸| 1区2区3区欧美| 久青草视频在线观看| 亚洲一级二级在线| www.国产毛片| 欧美精品丝袜久久久中文字幕| www.久久久久久久| 欧美日韩国产小视频| 欧美视频在线观看一区二区三区| 欧美日韩国产免费一区二区| 亚洲国产www| 亚洲片在线资源| www在线观看播放免费视频日本| 国产一区二区三区在线| 成人免费在线| 欧亚精品在线观看| 国语精品视频| 精品免费二区三区三区高中清不卡 | 午夜精品一区二区三区国产| 国产真实老熟女无套内射| 老司机午夜免费精品视频 | 中文字幕第69页| 亚洲一区二区三区四区五区中文| 成人涩涩小片视频日本| 一区二区久久久久| 一级黄色在线视频| 欧美sm极限捆绑bd| 3d成人动漫在线| 韩国三级日本三级少妇99| 国产香蕉久久| 久久精品国产一区二区三区日韩| 国产精品视屏| 手机成人av在线| 久久久久国产精品一区三寸 | 九九热只有精品| 日本久久电影网| 全部免费毛片在线播放一个| 日韩在线视频网站| 大胆人体一区二区| www.成人av| 国产精品久久久久久久| 日韩免费视频播放| 国产成人精品免费| 国产成人av免费在线观看| 一本色道**综合亚洲精品蜜桃冫| 天天爽夜夜爽人人爽| 日韩欧美美女一区二区三区| av福利在线播放| 日本欧美爱爱爱| 国产精品一区二区三区美女| 欧美h视频在线观看| 日韩avvvv在线播放| 野花社区视频在线观看| 亚洲国产精品嫩草影院| 精品国产99久久久久久宅男i | 黄色小视频在线免费观看| 欧美成年人在线观看| 精品久久在线| 亚洲国产精品一区二区第一页| 欧美+亚洲+精品+三区| 一道本在线免费视频| 国产午夜精品久久| 欧美超碰在线观看| 亚洲精品99久久久久| 欧美videossex另类| 91九色对白| 欧美日本不卡| 久久精品一二三四| 亚洲另类在线视频| 国产熟女精品视频| 久久中文久久字幕| 成人噜噜噜噜| 成人毛片100部免费看| 国产精品亚洲人在线观看| 欧美三级在线免费观看| 欧美一级黄色大片| 手机电影在线观看| 国产chinese精品一区二区| 欧美jjzz| 好男人香蕉影院| 图片区小说区国产精品视频| 日批视频免费播放| 91av国产在线| 亚洲v天堂v手机在线| 免费看a级黄色片| 国产精品三级视频| 国产精品欧美综合亚洲| 久久视频国产精品免费视频在线| 亚洲精品日产| 日韩av电影免费在线| 麻豆精品在线观看| 国产精品 欧美激情| 精品国产91久久久久久久妲己| wwwxxx在线观看| 国产一区二区在线免费| 欧美激情麻豆| 中文字幕在线视频播放| 岛国av一区二区| 秋霞av在线| 国产精品视频99| 午夜视频精品| 90岁老太婆乱淫| 欧美日韩亚洲综合在线 欧美亚洲特黄一级 | 精品美女在线观看| 在线能看的av网址| 亚洲bbw性色大片| 国产精品主播直播| 日本三级网站在线观看| 亚洲色图日韩av| 国产999精品在线观看| 69sex久久精品国产麻豆| 久久久www成人免费无遮挡大片| 日韩女同强女同hd| 永久免费精品影视网站| 精品视频在线播放一区二区三区| 色综合久久av| 国产一区二三区好的| 日本熟妇色xxxxx日本免费看| 日韩西西人体444www| h片视频在线观看| 午夜精品区一区二区三| 国产成人在线看| japanese国产在线观看| 欧美巨大黑人极品精男| 自拍亚洲一区| 色哟哟在线观看视频| 一本久久精品一区二区| 超碰个人在线| 欧美一区免费视频| 成人一二三区视频| 欧美激情第1页| 久久亚洲精品爱爱|