MySQL索引命中與失效代碼實現(xiàn)
創(chuàng)建表
SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(5) NOT NULL AUTO_INCREMENT COMMENT '用戶id', `username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用戶名', `password` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用戶密碼', `create_essay` int(5) NOT NULL COMMENT '原創(chuàng)文章', `user_visited` int(10) NOT NULL COMMENT '被訪問量', `user_rank` int(5) NOT NULL COMMENT '用戶排名', `perms` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `nickname` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用戶昵稱', PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 116856 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; SET FOREIGN_KEY_CHECKS = 1; // 創(chuàng)建組合索引 ALTER TABLE `user` ADD INDEX idx_username_password_user_rank (`username`,`password`,`user_rank`)
這里有一個組合索引的最左匹配原則:MySQL最左匹配原則
查看MySQL中索引是否命中可以使用explainh執(zhí)行優(yōu)化器來查看
MySQL執(zhí)行優(yōu)化器
執(zhí)行優(yōu)化器,顧名思義,優(yōu)化語句的,準(zhǔn)確來說是優(yōu)化查詢語句。其實就是在我們寫的select語句前加一個Explain關(guān)鍵字。
索引的命中與失效情況
第一種情況:針對聯(lián)合索引,是否遵循最左匹配原則;
建立一個組合索引
idx_username_password_user_rank(`username`,`password`,`user_rank`)
// 命中索引跟順序無關(guān) explain SELECT * from `user` where username = "liuxiangcheng" and password = "515239" and user_rank = 1 explain SELECT * from `user` where user_rank = 1 and username = "liuxiangcheng" and password = "515239" explain SELECT * from `user` where user_rank = 1 and password = "515239" and username = "liuxiangcheng"
結(jié)果:
第二種情況:去掉大哥,看看索引是否命中;
// 去掉大哥 explain SELECT * from `user` where password = "515239" and user_rank = 1
去掉大哥之后,索引失效,全表掃描。
第三種情況:在索引列上做了函數(shù)操作,會導(dǎo)致索引失效而導(dǎo)致全表掃描
我們先把那個聯(lián)合索引刪除掉,然后在username這一列上建立一個唯一索引:
刪除組合索引
drop index idx_username_password_user_rank on `user`
創(chuàng)建唯一索引
alter table `user` ADD UNIQUE key (`username`)
查看索引
explain SELECT * from `user` where username= 'user110819'
explain SELECT * from `user` where concat(username,'')= 'user110819'
第四種情況:模糊查詢前綴是以%開頭的,索引失效
explain SELECT * from `user` where username like '%user11081'
第五種情況:模糊查詢中后綴是以%,可以命中索引
explain SELECT * from `user` where username like 'user11081%'
第六種情況:使用is not null 會導(dǎo)致索引失效
explain SELECT * from `user` where username is not null
第六種情況:使用and時,其中有一個條件查詢帶有索引而另一個不帶索引,不會導(dǎo)致索引失效。而使用or時,如果條件查詢中其中一個不帶索引,導(dǎo)致索引失效,必須全部帶有索引。
and情況:
explain SELECT * from `user` where username = "liuxiangcheng" and password = "515239"
or情況:
explain SELECT * from `user` where username = "liuxiangcheng" or user_rank = 1
我們給user_rank加上索引
alter table `user` ADD index (`user_rank`)
再次查詢:
explain SELECT * from `user` where username = "liuxiangcheng" or user_rank = 1
第七種情況:使用不等于(!= 或者<>)的時候,會導(dǎo)致索引失效
explain SELECT * from `user` where user_rank != 1 or explain SELECT * from `user` where user_rank <> 1
第八種情況:使用范圍查詢之后索引失效
explain SELECT * from `user` where user_rank >(<,>=,<=) 1
第九種情況:隱式轉(zhuǎn)換可能會導(dǎo)致我們的索引失效
varchar類型,如果用int類型來查詢,索引失效
數(shù)據(jù)庫user表中我們的password是varchar類型
如果我們在條件查詢中使用整形來替代,那么這個時候索引就會失效,where varchar = int 索引失效
// password is varchar type explain SELECT * from `user` where password = 515239 explain SELECT * from `user` where password = '515239' explain SELECT * from `user` where password = "515239"
如果是int類型,我們使用varchar來替代,索引命中
// user_rank is int type explain SELECT * from `user` where user_rank = "1" explain SELECT * from `user` where user_rank = '1' explain SELECT * from `user` where user_rank = 1
總結(jié)隱式轉(zhuǎn)換:
- 當(dāng)操作符左右兩邊的數(shù)據(jù)類型不一致時,會發(fā)生隱式轉(zhuǎn)換。
- 當(dāng) where 查詢操作符左邊為數(shù)值類型時發(fā)生了隱式轉(zhuǎn)換,但是索引會命中,對查詢效率影響不大,但還是不推薦這么做。
- 當(dāng) where 查詢操作符左邊為字符類型時發(fā)生了隱式轉(zhuǎn)換,這樣會導(dǎo)致索引失效,造成全表掃描。
- 字符串轉(zhuǎn)換為數(shù)值類型時,非數(shù)字開頭的字符串會轉(zhuǎn)化為0,以數(shù)字開頭的字符串會截取從第一個字符到第一個非數(shù)字內(nèi)容為止的值為轉(zhuǎn)化結(jié)果。
總結(jié)
MySQL中索引失效的情況
1、組合索引中不遵循最左匹配原則,帶頭大哥不在,導(dǎo)致索引失效,全表掃描。
2、在索引列上做了函數(shù)操作,導(dǎo)致索引失效,全表掃描。
3、模糊查詢前綴是以%開頭的,導(dǎo)致索引失效,全表掃描。
4、使用is not null 會導(dǎo)致索引失效。
5、使用or時,如果條件查詢中其中一個不帶索引,導(dǎo)致索引失效,全表掃描。
6、使用不等于(!= 或者<>)的時候,會導(dǎo)致索引失效。
7、使用范圍查詢(>、<、>=、<=)之后索引失效。
8、隱式轉(zhuǎn)換可能會導(dǎo)致我們的索引失效。
查看MySQL中索引是否命中可以使用explainh執(zhí)行優(yōu)化器來查看。
到此這篇關(guān)于MySQL索引命中與失效代碼實現(xiàn)的文章就介紹到這了,更多相關(guān)MySQL索引命中與失效內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
小型Drupal數(shù)據(jù)庫備份以及大型站點MySQL備份策略分享
為了防止web服務(wù)器出現(xiàn)故障而引起的數(shù)據(jù)丟失,數(shù)據(jù)庫備份顯得非常重要,以免出現(xiàn)重大損失。本文分析研究一下小型的Drupal站的備份策略以及大型站點的mysql備份策略2014-11-11Centos8安裝mysql8的詳細過程(免安裝版/或者二進制包方式安裝)
這篇文章主要介紹了Centos8安裝mysql8的詳細過程(免安裝版/或者二進制包方式安裝),使用二進制包方式安裝首先檢查服務(wù)器上是否安裝有mysql然后開始安裝配置,本文分步驟給大家講解的非常詳細,需要的朋友可以參考下2022-11-11windows server2014 安裝 Mysql Applying Security出錯的完美解決方法
這篇文章給大家介紹了windows server2014 安裝 Mysql Applying Security出錯的完美解決方法,造成這種問題的主要原因是因為安裝一遍之后沒有卸載干凈,要解決這個問題需要注意以下幾點,具體解決方法,大家參考下本文2017-07-07Starting MySQL.Manager of pid-file quit without updating fil
因為硬盤滿了,Starting MySQL.Manager of pid-file quit without updating file.[FAILED]2010-02-02mysql執(zhí)行語句后只有錯誤代碼,沒有錯誤信息的問題
這篇文章主要介紹了mysql執(zhí)行語句后只有錯誤代碼,沒有錯誤信息的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-09-09