索引失效情况

##索引优化与查询优化

##创建数据库
CREATE DATABASE index_optimize;

##建表
CREATE TABLE `student` (
  `id` int NOT NULL AUTO_INCREMENT,
  `stuno` int DEFAULT NULL,
  `name` varchar(20) DEFAULT NULL,
  `age` int DEFAULT NULL,
  `classId` int DEFAULT NULL,
  PRIMARY KEY (`id`)
	#CONSTRAINT `fk_class_id` FOREIGN KEY (`classId`) REFERENCES 't_class' (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;


CREATE TABLE `class` (
  `id` int NOT NULL AUTO_INCREMENT,
  `className` varchar(30) DEFAULT NULL,
  `address` varchar(40) DEFAULT NULL,
  `monitor` int DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;


##创建函数

##生成随机字符串
CREATE DEFINER=`root`@`%` FUNCTION `rand_string`(n INT) RETURNS varchar(255) CHARSET utf8mb3
BEGIN
	DECLARE chars_str VARCHAR(100) DEFAULT
	'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
	DECLARE return_str VARCHAR(255) DEFAULT '';
	DECLARE i INT DEFAULT 0;
	WHILE i < n DO
		SET return_str = CONCAT(return_str,SUBSTRING(chars_str,FLOOR(1 + RAND() * 52),1));
		SET i = i + 1;
	END WHILE;
	RETURN return_str;
END


##生成随机数字
CREATE DEFINER=`root`@`%` FUNCTION `rand_num`(from_num INT,to_num INT) RETURNS int
BEGIN
	DECLARE i INT DEFAULT 0;
	SET i = FLOOR(from_num + RAND() * (to_num - from_num + 1));
	RETURN i;
END


##创建过程

##插入student表的过程
CREATE DEFINER=`root`@`%` PROCEDURE `insert_stu`(START INT, max_num INT)
BEGIN
DECLARE i INT DEFAULT 0;
	SET autocommit = 0;
	REPEAT
		SET i = i + 1;
		INSERT INTO student(stuno, name, age, classId) VALUES 
		((START + i),rand_string(6),rand_num(1,50),rand_num(1,1000));
		UNTIL i = max_num 
	END REPEAT;
	COMMIT;
END


##插入class表的过程
CREATE DEFINER=`root`@`%` PROCEDURE `insert_class`(max_num INT)
BEGIN
DECLARE i INT DEFAULT 0;
	SET autocommit = 0;
	REPEAT
		SET i = i + 1;
		INSERT INTO class(className, address, monitor) VALUES 
		(rand_string(8),rand_string(10),rand_num(1,100000));
		UNTIL i = max_num 
	END REPEAT;
	COMMIT;
END


##调用存储过程
CALL insert_class(10000); #班级表插入一万条
CALL insert_stu(100000,500000); #学生表插入五十万条




#1、全值匹配

EXPLAIN SELECT SQL_NO_CACHE * from student where age = 30;
EXPLAIN SELECT SQL_NO_CACHE * from student where age = 30 AND classId = 4;
EXPLAIN SELECT SQL_NO_CACHE * from student where age = 30 AND classId = 4 AND `name` = 'abcd';

CREATE INDEX idx_age on student(age);
CREATE INDEX idx_age_classId on student(age,classId);
CREATE INDEX idx_age_classId_name on student(age,classId,`name`);


#2、最左前缀

EXPLAIN SELECT SQL_NO_CACHE * from student where age = 30 AND `name` = 'abcd';  #联合索引失效,只有age的单列索引生效

EXPLAIN SELECT SQL_NO_CACHE * from student where classId = 4 AND `name` = 'abcd';  #索引失效

EXPLAIN SELECT SQL_NO_CACHE * from student where classId = 4 AND age = 30 AND    `name` = 'abcd';  #联合索引生效



#3、计算、函数、类型转换导致索引失效

CREATE index idx_name on student(`name`);

EXPLAIN SELECT SQL_NO_CACHE * from student where name like 'abc%';

EXPLAIN SELECT SQL_NO_CACHE * from student where left(name,3) = 'abc';  #索引失效



#4、联合索引中   范围条件右侧的列索引失效  
#例:index(age,classId,name)  此索引中如果classId是范围条件,那么name的索引会失效,与语句中写的顺序无关,优化器会优化
 
EXPLAIN SELECT SQL_NO_CACHE * from student where age = 30 and classId > 20 and `name` = 'abc';


#5、 !=  <> 会导致索引
EXPLAIN SELECT SQL_NO_CACHE * from student where name = 'abc';


#6、 is null可以使用到索引   is not null 会使索引失效
EXPLAIN SELECT SQL_NO_CACHE * from student where name is null;
EXPLAIN SELECT SQL_NO_CACHE * from student where name is not null; #索引失效


#7、like以%开头 索引失效
EXPLAIN SELECT SQL_NO_CACHE * from student where name like '%abc';

#8、or 前后存在非索引的列,索引失效
EXPLAIN SELECT SQL_NO_CACHE * from student where name = 'abc' or classId = 10; # name 和 classId 任意一个列上没有索引则语句不走索引





  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值