目录创建表Mysql执行优化器第一种情况:针对联合索引,是否遵循最左匹配原则;第二种情况:去掉大哥,看看索引是否命中;第三种情况:在索引列上做了函数操作,会导致索引失效而导致全表扫描第四种情况:模糊查询前缀是以%开头的,
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 '原创文章',
`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;
// 创建组合索引
ALTER TABLE `user` ADD INDEX idx_username_password_user_rank (`username`,`password`,`user_rank`)
这里有一个组合索引的最左匹配原则:MySQL最左匹配原则
查看MySQL中索引是否命中可以使用explainh执行优化器来查看
执行优化器,顾名思义,优化语句的,准确来说是优化查询语句。其实就是在我们写的select语句前加一个Explain关键字。
索引的命中与失效情况
建立一个组合索引
idx_username_password_user_rank(`username`,`password`,`user_rank`)
// 命中索引跟顺序无关
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"
结果:
// 去掉大哥
explain SELECT * from `user` where password = "515239" and user_rank = 1
去掉大哥之后,索引失效,全表扫描。
我们先把那个联合索引删除掉,然后在username这一列上建立一个唯一索引:
删除组合索引
drop index idx_username_password_user_rank on `user`
创建唯一索引
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%'
explain SELECT * from `user` where username is not null
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
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
varchar类型,如果用int类型来查询,索引失效
数据库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
总结隐式转换:
1、组合索引中不遵循最左匹配原则,带头大哥不在,导致索引失效,全表扫描。
2、在索引列上做了函数操作,导致索引失效,全表扫描。
3、模糊查询前缀是以%开头的,导致索引失效,全表扫描。
4、使用is not null 会导致索引失效。
5、使用or时,如果条件查询中其中一个不带索引,导致索引失效,全表扫描。
6、使用不等于(!= 或者<>)的时候,会导致索引失效。
7、使用范围查询(>、<、>=、<=)之后索引失效。
8、隐式转换可能会导致我们的索引失效。
到此这篇关于MySQL索引命中与失效代码实现的文章就介绍到这了,更多相关MySQL索引命中与失效内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
--结束END--
本文标题: MySQL索引命中与失效代码实现
本文链接: https://lsjlt.com/news/177842.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-10-23
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
2024-10-22
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0