# 原文链接 https://blog.csdn.net/uuqaz/article/details/123990120CREATE TABLE `t_user` ( `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID', `id_no` VARCHAR(18) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '身份编号', `username` VARCHAR(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '用户名', `age` INT(11) DEFAULT NULL COMMENT '年龄', `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', PRIMARY KEY (`id`), KEY `union_idx` (`id_no`,`username`,`age`), KEY `create_time_idx` (`create_time`)) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;-- 删除历史存储过程DROP PROCEDURE IF EXISTS `insert_t_user`-- 创建存储过程DELIMITER $$CREATE PROCEDURE insert_t_user(IN limit_num INT)BEGINDECLARE i INT DEFAULT 10;DECLARE id_no VARCHAR(18) ;DECLARE username VARCHAR(32) ;DECLARE age TINYINT DEFAULT 1;WHILE i < limit_num DOSET id_no = CONCAT("NO", i);SET username = CONCAT("Tom",i);SET age = FLOOR(10 + RAND()*2);INSERT INTO `t_user` VALUES (NULL, id_no, username, age, NOW());SET i = i + 1;END WHILE;END $$-- 调用存储过程CALL insert_t_user(100);
# 查看索引SHOW INDEX FROM t_user;# 在联合索引的场景下,查询条件不满足最左匹配原则。EXPLAIN SELECT * FROM t_user WHERE id_no = '1002'; # 复合索引EXPLAIN SELECT * FROM t_user WHERE id_no = '1002' AND username = 'Tom2'; # 复合索引EXPLAIN SELECT * FROM t_user WHERE id_no = '1002' AND age = 12; # 只走了id_noEXPLAIN SELECT * FROM t_user WHERE username = 'Tom2' AND age = 12; # 不走, 不满足最左前缀原则# 索引列参与了函数处理,会导致全表扫描,索引失效。EXPLAIN SELECT * FROM t_user WHERE SUBSTR(id_no,1,3) = '100';# 错误的Like使用:模糊查询时(like语句),模糊匹配的占位符位于条件的首部EXPLAIN SELECT * FROM t_user WHERE id_no LIKE '%00%';# 类型隐式转换EXPLAIN SELECT * FROM t_user WHERE id_no = 1002;# 特例,如果字段类型为int类型,而查询条件添加了单引号或双引号,则Mysql会参数转化为int类型,虽然使用了单引号或双引号:EXPLAIN SELECT * FROM t_user WHERE id = '2';DESC t_user;# 查询条件使用or关键字,其中一个字段没有创建索引,则会导致整个查询语句索引失效; or两边为“>”和“<”范围查询时,索引失效EXPLAIN SELECT * FROM t_user WHERE id = 2 OR username = 'Tom2';# 两列数据做比较,即便两列都创建了索引,索引也会失效。EXPLAIN SELECT * FROM t_user WHERE id > age;# 查询条件使用is null时正常走索引,使用is not null时,不走索引。EXPLAIN SELECT * FROM t_user WHERE id_no IS NULL;EXPLAIN SELECT * FROM t_user WHERE id_no IS NOT NULL;# in、exists、not in、not exists、between and. EXPLAIN SELECT * FROM t_user WHERE id IN (2,3);EXPLAIN SELECT * FROM t_user WHERE id_no IN ('1001','1002');EXPLAIN SELECT * FROM t_user u1 WHERE EXISTS (SELECT 1 FROM t_user u2 WHERE u2.id = 2 AND u2.id = u1.id);EXPLAIN SELECT * FROM t_user WHERE id_no BETWEEN '1002' AND '1003';# 查询条件使用not in时,如果是主键则走索引,如果是普通索引,则索引失效。EXPLAIN SELECT * FROM t_user WHERE id NOT IN (2,3);EXPLAIN SELECT * FROM t_user WHERE id_no NOT IN('1002' , '1003');# 查询条件使用not exists时,索引失效。EXPLAIN SELECT * FROM t_user u1 WHERE NOT EXISTS (SELECT 1 FROM t_user u2 WHERE u2.id = 2 AND u2.id = u1.id);# order by导致索引失效EXPLAIN SELECT * FROM t_user ORDER BY id_no ;# 特例主键使用order by时,可以正常走索引。EXPLAIN SELECT * FROM t_user ORDER BY id DESC;