日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

MySQL選錯索引的原因以及解決方案

瀏覽:31日期:2023-10-10 15:38:22

MySQL 中,可以為某張表指定多個索引,但在語句具體執(zhí)行時,選用哪個索引是由 MySQL 中執(zhí)行器確定的。那么執(zhí)行器選擇索引的原則是什么,以及會不會出現選錯索引的情況呢?

先看這樣一個例子:

創(chuàng)建表 Y,設置兩個普通索引, 創(chuàng)建一個存儲過程用于插入數據。

MySQL: 5.7.27, 隔離級別: RR

CREATE TABLE `Y` ( `id` int(11) NOT NULL AUTO_INCREMENT, `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `a` (`a`), KEY `b` (`b`)) ENGINE=InnoDB;

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

查看如下事務:

Session A Session B start transaction with consistent snapshot; delete from t; call idata(); explain select * from Y where a between 10000 and 20000; explain select * from Y force index(a) where a between 10000 and 20000; commit;

如果單獨執(zhí)行 Session B 中 select * from Y where a between 10000 and 20000;,毫無疑問會選擇 a 這個索引。

但如果安裝 Session A,Session B 的順序執(zhí)行,發(fā)現索引的選擇如下:

MySQL選錯索引的原因以及解決方案

可以發(fā)現,在 Session B 的場景下,執(zhí)行器卻沒有選擇 a 所在的索引,而是選擇基于主鍵索引的全表掃描。

set long_query_time=0;--將慢查詢日志打開,并將闕值設為 0. 在記錄的日志中,可以發(fā)現 MySQL 并沒有選擇 a 所在的索引,同時花費了更長的時間。

這樣看,MySQL 的優(yōu)化器不一定每次都能選擇合適的索引。想要理解出現該現象的原因,就要從優(yōu)化器的選擇邏輯說起。

優(yōu)化器

MySQL 中優(yōu)化器的目的就是找到一個最優(yōu)的執(zhí)行方案,從而用最小的代價去執(zhí)行語句。

優(yōu)化器在選擇索引時,主要會考慮如下的因素:

掃描的行數:掃描的行數越少,就證明訪問磁盤數據的次數越少,消耗的 CPU 資源就越少。 有沒有涉及到臨時表 排序

關于掃描行數的確定

計算索引的基數

MySQL 在執(zhí)行語句前,其實并不能準確的計算出掃描的行數,而是通過數學統(tǒng)計信息來估算記錄數。這個統(tǒng)計信息被稱為索引的“區(qū)分度”,在索引上不同的值越多,區(qū)分度就越高。在一個索引上不同值的個數,稱為“基數”?;鶖翟酱?,索引的區(qū)分度越好。

MySQL選錯索引的原因以及解決方案

這里的 Cardinality 就是索引的基數,但基數并不是完全準確的。MySQL 是在獲取基數時,實際上是采用采樣統(tǒng)計的方式。

計算時,會選擇 N 個數據頁,并統(tǒng)計這些頁面上的不同值,得到一個平均值,然后乘以該索引的頁面數,然后得到的就是索引的基數。

在 MySQL 中,有兩種存儲索引的方式,可通過設置 innodb_stats_persistent 來切換:

on 時:表示統(tǒng)計信息會持久化存儲,默認 N 為 20,M 為 10. off 時,統(tǒng)計信息僅會存儲在內存中,默認 N 為 8,M 為 16.

由于表中數據是不斷變化的,所以當更新的值超過 1/M 時,會自動觸發(fā)索引統(tǒng)計。

但需要注意的是,由于是采樣統(tǒng)計,所以基數的值不是準確的。

預估掃描行數的錯誤

之前看到,執(zhí)行 Select * from Y where a between 10000 and 20000 預估的行數是 100015,這個是能理解的,因為走的是全表掃描。

之后執(zhí)行 select * from Y force index(a) where a between 10000 and 20000 預估的行數是 37116,這個就不能理解了,理想的情況下應該是 10001 行 (需要遍歷到 20001)。

而且更奇怪的是,雖然 37116 行的預估行數不太合理,但也遠小于全表掃描的 100015,為什么優(yōu)化器還是選擇全表掃描呢?

首先先看第二個問題,選擇 100015 的原因是因為如果使用索引 a 的話,除了需要在 a 索引掃描外,還需要回表,主鍵索引上的查詢代價,優(yōu)化器也需要算進去,所以選擇了全表掃描。

這時再看第一個問題,為什么沒有得到正確的行數。這個就和一致性視圖有關了,首先 Session A 中,開啟了一致性視圖,并沒有提交。之后的 Session 清空了 Y 表后,又重新創(chuàng)建了相同的數據,這時每行數據都有兩個版本,舊版本是 delete 前的數據,新版本是標記為刪除的數據。所以索引 a 上的數據其實有兩份。也就造成了行數的預估錯誤。

mysql 是通過標記刪除的方法來刪除記錄的,并不是在索引和數據文件中真正的刪除。而且由于一致性讀的保證,不能刪除 delete 的空間,再加上 insert 的空間。導致統(tǒng)計信息有誤。

選用錯誤索引的解決辦法

對于行數預估錯誤的情況, 可采用如下的方法:

如果遇到 EXPLAIN 和預估的行數,數值相差較大時,可以通過analyze table 來重新統(tǒng)計索引信息。

MySQL選錯索引的原因以及解決方案

直接通過 force index 強制指定需要使用的索引,不讓優(yōu)化器進行判斷。但使用 force 也可能帶來一些問題:

遷移數據庫時,語法不支持 不容易變更并且不太方便,因為選錯索引的情況一般不會經常發(fā)生,在生產環(huán)境出現問題后,才需要改代碼,但還需要重新進行上線測試,部署。

優(yōu)化 SQL 語句,引導優(yōu)化器使用正確的索引

再看一個類似的例子:

MySQL選錯索引的原因以及解決方案

先來看一下這句

SQL select * from Y where a between 1 and 1000 and b between5000 100000 order by b limit 1;

在執(zhí)行這句話時,可以選索引 a,也可以選索引 b. 我們知道,每個索引對應了一顆B+樹。這里由于取得是 a 和 b 的交集,如果選用索引 a 的話,需要遍歷 1 - 10001 行。選用索引 b 需要遍歷 50000 - 100001 行。理論上來說,應該選擇 a 作為索引,可以優(yōu)化器又偏偏選擇了 b 作為索引。

這里選擇 b 作為索引的原因,是因為優(yōu)化器看到了后面的 order by 語句,由于要排序,而 B+ 樹本身就是有序的,省去了排序的過程,所以選擇了 b 作為索引。

但從實際的執(zhí)行時間來看,索引 a 執(zhí)行時間更短,所以這里 MySQL 又選擇了錯誤的索引。

我們可以將上述語句中 order by b limit 改為 order by b,a limit 1 這時由于 a,b 索引都要排序,掃描的行數就成為執(zhí)行器主要參考的條件,引導選擇正確的索引。

這樣做的前提一定要保證執(zhí)行的邏輯結果是一致的,比如在 limit 1 的情況下,order by b,a 和 order by b 的結果一致,如果換成 limit 100 就不一定了。

MySQL選錯索引的原因以及解決方案

還有一種改發(fā)

select * from (select * from t where (a between 1 and 1000) and (b between 50000 and 100000) order by b limit 100)alias limit 1;

現在可以看到,優(yōu)化器選擇了合適的索引。原因在于 limit 100 讓優(yōu)化器認為,使用索引 b 的代價較高,進而選擇索引 a. 其實就是通過 limit 100 誘導優(yōu)化器做出選擇。

調整索引

能否找到更優(yōu),更合適的索引,或者利用索引的原則,刪除一些不必要的索引。

總結

現在我們知道,MySQL 在選擇索引時,是會出現錯誤的情況的。優(yōu)化器選擇索引的原則主要有三個,掃描的行數,是否存在臨時表,以及排序。行數的掃描,主要和基數有關,而基數的統(tǒng)計則是通過統(tǒng)計抽樣決定的,進而預估的行數可能會是不準確的。

在遇到掃描的行數不正確時,可以通過 analyze table 來重新統(tǒng)計表的信息,通過 force index 強制指定索引,或通過手動改變 sql 的語義,誘導優(yōu)化器做出正確的選擇。

以上就是MySQL選錯索引的原因以及解決方案的詳細內容,更多關于MySQL 索引的資料請關注好吧啦網其它相關文章!

標簽: MySQL 數據庫
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日本va欧美va欧美va精品| 欧美另类专区| 久久高清免费观看| 亚洲一区二区av| 国产精品中文字幕亚洲欧美| 成人免费一区| 国产精品玖玖玖在线资源| 色综合五月天| 最新日韩欧美| 国产日韩一区二区三区在线| 欧美日韩国产一区二区在线观看| 国产黄大片在线观看| 久久久久久久欧美精品| 亚洲神马久久| 亚洲色图网站| 欧美精品三级在线| 亚洲二区视频| 欧美亚洲人成在线| 99免费精品| 中文字幕一区二区三区在线视频| 久久亚洲图片| 国产精品白丝久久av网站| 中文字幕在线官网| 久久黄色影院| 久久精品国语| 国产免费播放一区二区| 国产精品白丝av嫩草影院| 美女毛片一区二区三区四区| 久久gogo国模啪啪裸体| 黄色网一区二区| 久久国产毛片| 视频一区日韩精品| 欧美激情麻豆| 中文av在线全新| 免费久久精品视频| 日本美女一区| 亚洲精品综合| 国产精品玖玖玖在线资源| 91久久久久| 亚洲综合在线电影| 欧美在线网站| 欧美中文高清| 色欧美自拍视频| 亚洲涩涩av| 国产传媒在线| 欧美午夜三级| 伊伊综合在线| 国产毛片久久| 国产一区调教| 婷婷久久免费视频| 在线看片不卡| 日韩免费小视频| 一区二区日韩免费看| 国产精品调教视频| 国产超碰精品| 日韩va欧美va亚洲va久久| 99久久婷婷这里只有精品| 亚洲精品动态| 成人国产精品久久| 蜜桃视频第一区免费观看| 黄毛片在线观看| 日韩av网站在线观看| 国产精品专区免费| 国产一区 二区| av一区二区高清| 国产精品久久久久久久久久白浆 | 成人av三级| 亚洲2区在线| 人人草在线视频| 国产精品久久777777毛茸茸| 亚洲欧美视频一区二区三区| 精品三区视频| 97精品国产一区二区三区| 亚洲一区黄色| 亚洲三级精品| 日韩一区二区三免费高清在线观看| 天堂成人免费av电影一区| 中文亚洲欧美| 免费美女久久99| 奇米777国产一区国产二区| 日本大胆欧美人术艺术动态| 三级在线看中文字幕完整版| 日韩中文字幕区一区有砖一区| 亚洲一区欧美| 日韩免费在线| 亚洲精品一区二区在线看| 国产一区二区三区四区大秀 | 麻豆视频在线观看免费网站黄 | 日韩精品一区二区三区中文| 亚洲免费资源| 亚洲精品麻豆| 国产精品一区二区三区美女| 国产精品探花在线观看| 中文在线а√天堂| 国产一卡不卡| 国产精品视区| 亚洲网站视频| 亚洲精品在线影院| 久久久人人人| 日韩成人精品一区二区| 国产伦精品一区二区三区视频| 日韩精品中文字幕吗一区二区| 亚洲精品字幕| 亚洲精品第一| 日韩高清在线不卡| 国产精品一区二区99| 国产精品chinese| 精品在线网站观看| 精品网站999| 亚洲精品永久免费视频| 亲子伦视频一区二区三区| 久久精品播放| 亚洲免费高清| 天堂va在线高清一区| 日本免费在线视频不卡一不卡二| 欧美一级一区| 国产在视频一区二区三区吞精| 四季av一区二区凹凸精品| 日韩欧美在线中字| 亚洲调教视频在线观看| 亚洲欧美不卡| 欧美亚洲三级| 国产第一亚洲| 午夜av成人| 亚洲在线成人| 久久国产生活片100| 国产精品日韩精品中文字幕| 国产66精品| 一区免费在线| 久久国产婷婷国产香蕉| 98精品视频| 久久亚洲图片| 久久99精品久久久久久园产越南| 水蜜桃久久夜色精品一区| 亚州av乱码久久精品蜜桃| 日韩精品一卡二卡三卡四卡无卡| 亚洲欧美久久精品| 国产成人免费精品| 久久一级电影| 日韩一区精品| 日本午夜大片a在线观看| 老鸭窝亚洲一区二区三区| 国产精品国产三级在线观看| 国产在线观看www| 性色一区二区| 国产精品亚洲二区| 欧美性感美女一区二区| 欧美影院视频| 欧美日韩精品在线一区| 日本免费新一区视频| 桃色一区二区| 日韩影片在线观看| 亚洲91视频| 日韩中文一区二区| 国产伦久视频在线观看| 亚洲永久字幕| 欧美激情视频一区二区三区在线播放| 性感美女一区二区在线观看| 日韩精品一区二区三区中文字幕| 日韩欧美一区二区三区在线视频 | 国产精品腿扒开做爽爽爽挤奶网站| 奇米色欧美一区二区三区| 久久精品电影| 国产免费av一区二区三区| 激情综合自拍| 你懂的国产精品| 午夜亚洲福利在线老司机| 国产精品国产一区| 日本午夜精品久久久久| 狠狠操综合网| 成人午夜网址| 91精品尤物| 麻豆精品91| 国内精品福利| 黄色网一区二区| 欧美日韩一区二区三区不卡视频 | 日韩在线一二三区| 日韩国产激情| 国产日韩欧美一区| 久久国产成人| 日本不卡免费高清视频在线| 国产欧美在线| 日本一区二区三区视频在线看| 亚洲高清不卡| 狠狠久久伊人| 国产精品nxnn| 婷婷综合国产| 中文字幕日韩高清在线| 久久精品影视| 91视频一区| 欧美国产不卡| 国产精品尤物| **爰片久久毛片| 日本aⅴ亚洲精品中文乱码| 国产一区91| 一区在线视频观看| 日韩精品首页| 日韩精品91| 精品三级av| 国产精品久久久久毛片大屁完整版|