MySQL之主鍵索引排序失效問題
主鍵索引排序失效
環(huán)境:MySQL8
有一張用戶信息表user_info
,建表DDL如下:
CREATE TABLE `user_info` ( `id` int(11) NOT NULL COMMENT '用戶編號', `age` int(11) NOT NULL COMMENT '用戶年齡', PRIMARY KEY (`id`), KEY `idx_age` (`age`) USING BTREE COMMENT '年齡索引' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
只有兩列,第一列用戶編號id
做主鍵,第二列用戶年齡age
有一個普通索引idx_age
。
現(xiàn)在初始化幾行數(shù)據(jù)
INSERT INTO `user_info` (`id`,`age`) VALUES(1,1),(5,3),(7,8),(11,12);
查一下所有記錄
接著往這個表里插入一行數(shù)據(jù)(6,1)
,猜測一下這行數(shù)據(jù)最終會插入在什么位置?
可能大部分人都會認(rèn)為插入在(5,3)
和(7,8)
之間,因為id=6的話,5<6<7。
但是再次查看結(jié)果,發(fā)現(xiàn)并符合預(yù)期,而是插入在了(1,1)
和(5,3)
之間:
看起來效果就像是age
變?yōu)榱酥麈I,根據(jù)age
默認(rèn)排序了,或者說主鍵索引排序失效。
這是因為在MySQL底層實現(xiàn)中,對于像user_info
這種特殊的表,有特殊的處理方式。這張user_info
表的特殊點在于,只有兩列,一列是主鍵,另一列也有索引。
這時候非主鍵的age這一列就是一個覆蓋索引
,因為age的索引可以查到所有字段。
MySQL內(nèi)部會認(rèn)為訪問數(shù)據(jù)的時候,覆蓋索引的效率比主鍵索引高,所以維護(hù)默認(rèn)的排序會優(yōu)先根據(jù)覆蓋索引列來進(jìn)行。
查看一下執(zhí)行計劃
type=index
,代表只遍歷了索引樹;key=idx_age
,代表真正用到了索引;Extra=Using index
,代表覆蓋索引生效,在索引樹中就可以查到所需數(shù)據(jù),避免了回表掃描表數(shù)據(jù)文件。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
ubuntu 16.04下mysql5.7.17開放遠(yuǎn)程3306端口
這篇文章主要介紹了ubuntu 16.04下mysql5.7.17開放遠(yuǎn)程3306端口的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-01-01解決Mysql:ERROR?1045?(28000):Access?denied?for?user?‘roo
最近在我們連接數(shù)據(jù)庫的時候遇到個問題,感覺還挺容易遇到的,所以總結(jié)下,這篇文章主要給大家介紹了關(guān)于解決Mysql:ERROR?1045?(28000):Access?denied?for?user?‘root‘@‘localhost‘?(using?password:?NO)的方法,需要的朋友可以參考下2022-06-06