MySQL索引命中與失效代碼實(shí)現(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`)
這里有一個(gè)組合索引的最左匹配原則:MySQL最左匹配原則
查看MySQL中索引是否命中可以使用explainh執(zhí)行優(yōu)化器來(lái)查看
MySQL執(zhí)行優(yōu)化器
執(zhí)行優(yōu)化器,顧名思義,優(yōu)化語(yǔ)句的,準(zhǔn)確來(lái)說是優(yōu)化查詢語(yǔ)句。其實(shí)就是在我們寫的select語(yǔ)句前加一個(gè)Explain關(guān)鍵字。
索引的命中與失效情況
第一種情況:針對(duì)聯(lián)合索引,是否遵循最左匹配原則;
建立一個(gè)組合索引
idx_username_password_user_rank(`username`,`password`,`user_rank`)
// 命中索引跟順序無(wú)關(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ù)操作,會(huì)導(dǎo)致索引失效而導(dǎo)致全表掃描
我們先把那個(gè)聯(lián)合索引刪除掉,然后在username這一列上建立一個(gè)唯一索引:
刪除組合索引
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 會(huì)導(dǎo)致索引失效
explain SELECT * from `user` where username is not null
第六種情況:使用and時(shí),其中有一個(gè)條件查詢帶有索引而另一個(gè)不帶索引,不會(huì)導(dǎo)致索引失效。而使用or時(shí),如果條件查詢中其中一個(gè)不帶索引,導(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
第七種情況:使用不等于(!= 或者<>)的時(shí)候,會(huì)導(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)換可能會(huì)導(dǎo)致我們的索引失效
varchar類型,如果用int類型來(lái)查詢,索引失效
數(shù)據(jù)庫(kù)user表中我們的password是varchar類型
如果我們?cè)跅l件查詢中使用整形來(lái)替代,那么這個(gè)時(shí)候索引就會(huì)失效,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來(lái)替代,索引命中
// 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ù)類型不一致時(shí),會(huì)發(fā)生隱式轉(zhuǎn)換。
- 當(dāng) where 查詢操作符左邊為數(shù)值類型時(shí)發(fā)生了隱式轉(zhuǎn)換,但是索引會(huì)命中,對(duì)查詢效率影響不大,但還是不推薦這么做。
- 當(dāng) where 查詢操作符左邊為字符類型時(shí)發(fā)生了隱式轉(zhuǎn)換,這樣會(huì)導(dǎo)致索引失效,造成全表掃描。
- 字符串轉(zhuǎn)換為數(shù)值類型時(shí),非數(shù)字開頭的字符串會(huì)轉(zhuǎn)化為0,以數(shù)字開頭的字符串會(huì)截取從第一個(gè)字符到第一個(gè)非數(shù)字內(nèi)容為止的值為轉(zhuǎn)化結(jié)果。
總結(jié)
MySQL中索引失效的情況
1、組合索引中不遵循最左匹配原則,帶頭大哥不在,導(dǎo)致索引失效,全表掃描。
2、在索引列上做了函數(shù)操作,導(dǎo)致索引失效,全表掃描。
3、模糊查詢前綴是以%開頭的,導(dǎo)致索引失效,全表掃描。
4、使用is not null 會(huì)導(dǎo)致索引失效。
5、使用or時(shí),如果條件查詢中其中一個(gè)不帶索引,導(dǎo)致索引失效,全表掃描。
6、使用不等于(!= 或者<>)的時(shí)候,會(huì)導(dǎo)致索引失效。
7、使用范圍查詢(>、<、>=、<=)之后索引失效。
8、隱式轉(zhuǎn)換可能會(huì)導(dǎo)致我們的索引失效。
查看MySQL中索引是否命中可以使用explainh執(zhí)行優(yōu)化器來(lái)查看。
到此這篇關(guān)于MySQL索引命中與失效代碼實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)MySQL索引命中與失效內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
小型Drupal數(shù)據(jù)庫(kù)備份以及大型站點(diǎn)MySQL備份策略分享
為了防止web服務(wù)器出現(xiàn)故障而引起的數(shù)據(jù)丟失,數(shù)據(jù)庫(kù)備份顯得非常重要,以免出現(xiàn)重大損失。本文分析研究一下小型的Drupal站的備份策略以及大型站點(diǎn)的mysql備份策略2014-11-11Centos8安裝mysql8的詳細(xì)過程(免安裝版/或者二進(jìn)制包方式安裝)
這篇文章主要介紹了Centos8安裝mysql8的詳細(xì)過程(免安裝版/或者二進(jìn)制包方式安裝),使用二進(jìn)制包方式安裝首先檢查服務(wù)器上是否安裝有mysql然后開始安裝配置,本文分步驟給大家講解的非常詳細(xì),需要的朋友可以參考下2022-11-11windows server2014 安裝 Mysql Applying Security出錯(cuò)的完美解決方法
這篇文章給大家介紹了windows server2014 安裝 Mysql Applying Security出錯(cuò)的完美解決方法,造成這種問題的主要原因是因?yàn)榘惭b一遍之后沒有卸載干凈,要解決這個(gè)問題需要注意以下幾點(diǎn),具體解決方法,大家參考下本文2017-07-07
![Starting MySQL.Manager of pid-file quit without updating file.[FAILED]的解決方法](http://img.jbzj.com/images/xgimg/bcimg6.png)
Starting MySQL.Manager of pid-file quit without updating fil

mysql執(zhí)行語(yǔ)句后只有錯(cuò)誤代碼,沒有錯(cuò)誤信息的問題

MySQL?Test?Run?測(cè)試框架詳細(xì)介紹?