10講MySQL為什么有時(shí)候會(huì)選錯(cuò)索引

1 使用存儲(chǔ)過(guò)程生成假數(shù)據(jù)

delimiter ;;
create procedure idata()
begin
  declare i int;
  set i=1;
  while(i<=100000)do
    insert into t values(i, i, i);
    set i=i+1;
  end while;
end;;
delimiter ;
call idata();

2 會(huì)走索引 select * from t where a between 10000 and 20000;
3 一個(gè) mysql 選錯(cuò)索引的案例

image.png

4 slow log 可以查看具體執(zhí)行情況
5 force index(a)可以強(qiáng)制使用索引
6 set long_query_time=0; 所有語(yǔ)句都會(huì)被記錄到 slow log
7 slow log 結(jié)果

image.png

8 如何查看 slow log
9 對(duì)應(yīng)的是平常 “不斷刪除歷史數(shù)據(jù)和新增數(shù)據(jù)”的場(chǎng)景 , 此時(shí)會(huì)選錯(cuò)索引
10 優(yōu)化器的目的 , 最小的代價(jià)執(zhí)行語(yǔ)句 , 最小代價(jià) : 掃描行數(shù)少 , 則 IO 少,CPU 消耗少
11 優(yōu)化器其他判斷準(zhǔn)則 , 是否使用臨時(shí)表 , 是否需要排序
12 執(zhí)行語(yǔ)句之前優(yōu)化器并不能精確判斷掃描行數(shù)
13 通過(guò)使用”區(qū)分度”進(jìn)行預(yù)估
14 區(qū)分度就是索引上的cardinality(基數(shù)) , 越大區(qū)分度越好
15 cardinality是通過(guò)采樣統(tǒng)計(jì)取值的 , 并不精確
16 采樣統(tǒng)計(jì)的方法 : 取n個(gè)數(shù)據(jù)頁(yè) , 取不同值數(shù)的平均值 , 乘以數(shù)據(jù)頁(yè)數(shù)量
17 當(dāng)變更的數(shù)據(jù)超過(guò)1/M的時(shí)候會(huì)重新采樣統(tǒng)計(jì)
18 采樣統(tǒng)計(jì)可存在磁盤中或只存在內(nèi)存中
19 通過(guò)innodb_stats_persistent修改 , on 是持久化,N是20,M是10 , off 是內(nèi)存中,N是8,M是16
20 采樣統(tǒng)計(jì)的值還是很容易不準(zhǔn)的 , 但大體上依然是差不多的
21 上面那個(gè)案例的兩個(gè)語(yǔ)句的預(yù)估行數(shù)

image.png

image.png


22 Q1 語(yǔ)句的預(yù)估行數(shù)是接近的 , 但是 Q2 的預(yù)估行數(shù)是錯(cuò)誤的
23 此時(shí)由于優(yōu)化器還需要考慮回表去掃描的代價(jià) , 并且認(rèn)為直接掃描主鍵索引更快 , 因此當(dāng)不 force index 的時(shí)候會(huì)用全表掃描 , 但顯然從執(zhí)行時(shí)間來(lái)看不是最快的

23 但是主要的問(wèn)題還是錯(cuò)誤的預(yù)估行數(shù)造成的 , 圖 1 就沒問(wèn)題啊
24 analyze table t , 重建 統(tǒng)計(jì)

image.png

25 另一個(gè)案例 , 說(shuō)明優(yōu)化器不只通過(guò)預(yù)估行數(shù)來(lái)分析
26 select * from t where (a between 1 and 1000) and (b between 50000 and 100000) order by b limit 1;
27 幾種解決方案 , 1 修改語(yǔ)義 2 刪除不必要的索引 3 force index
28 思考題 : 為什么單獨(dú)delete的話預(yù)估行數(shù)正常 , 但session a沒提交的時(shí)候則不正常 ? 因?yàn)閟ession a沒提交 , 數(shù)據(jù)是不能刪除的 , 相當(dāng)于有兩份數(shù)據(jù)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 索引是應(yīng)用程序設(shè)計(jì)和開發(fā)的一個(gè)重要方面。 若索引太多, 應(yīng)用程序的性能可能會(huì)受到影響。 而索引太少, 對(duì)查詢性能又...
    好好學(xué)習(xí)Sun閱讀 1,125評(píng)論 0 4
  • 今天看到一位朋友寫的mysql筆記總結(jié),覺得寫的很詳細(xì)很用心,這里轉(zhuǎn)載一下,供大家參考下,也希望大家能關(guān)注他原文地...
    信仰與初衷閱讀 4,842評(píng)論 0 30
  • 2個(gè)字段 a,b 上都有索引 t 中插入 10 萬(wàn)行記錄,取值按整數(shù)遞增,即:(1,1,1),(2,2,2),(3...
    胖達(dá)_4b7e閱讀 1,713評(píng)論 1 1
  • [TOC] MySQL索引和SQL調(diào)優(yōu) 本文有參考網(wǎng)上其他相關(guān)文章,本文最后有附參考的鏈接 MySQL索引 MyS...
    AllenWu閱讀 2,644評(píng)論 0 43
  • 本文主要總結(jié)了工作中一些常用的操作及不合理的操作,在對(duì)慢查詢進(jìn)行優(yōu)化時(shí)收集的一些有用的資料和信息,本文適合有MyS...
    Chting閱讀 687評(píng)論 0 1

友情鏈接更多精彩內(nèi)容