mysql索引

什么是回表?

1.首先创建一个简单的学生排名表

create table student (
ID int(11) primary key,
CLASS_RANKING int NOT NULL DEFAULT 0, 
STUDENT_NAME varchar(16) NOT NULL DEFAULT '',
index CLASS_RANKING(CLASS_RANKING))
engine=InnoDB;

insert into T values(11111,1, 'zs'),(22222,2,'ls'),(33333,3,'ww'),(44444,4,'zl'),(55555,5,'lm'),(66666,6,'ll');

2.使用查询 select * from student where CLASS_RANKING between 3 and 4

这条 SQL 查询语句的执行流程:在 CLASS_RANKING 索引树上找到 CLASS_RANKING=3 的记录,取得 ID = 33333;再到 ID 索引树查到 ID=33333 对应的 值;在 CLASS_RANKING 索引树取下一个值 k=44444,取得 ID=44444;再回到 ID 索引树查到 ID=44444 对应的值;在 k 索引树取下一个值 k=5,不满足条件,循环结束。像这种回到主键索引树搜索的过程,称为回表

覆盖索引

还是刚才那张表,如果使用(select ID from student where CLASS_RANKING between 3 and 4),这个sql查询时,因为ID在CLASS_RANKING 索引树上,可以直接提供查询结果,不需要回表,相当于CLASS_RANKING 索引树覆盖了我们的查询需求,这样操作称为覆盖索引。

优点:减少树的搜索次数

最左前缀原则

首先按照下面sql创建表

CREATE TABLE `SCHOOL_STUDENT_INFO` (
  `ID` int(11) NOT NULL,
  `STUDENT_CARD` varchar(32) DEFAULT NULL,
  `NAME` varchar(32) DEFAULT NULL,
  `AGE` int(11) DEFAULT NULL,
  `CLASS_NUM` varchar(32) DEFAULT NULL,
   ... 地址等信息....
  PRIMARY KEY (`ID`),
  KEY `STUDENT_CARD` (`STUDENT_CARD`),
  KEY `NAME_AGE` (`NAME`,`AGE`)
) ENGINE=InnoDB

按照以上的建表,如果根据学号(STUDENT_CARD)查询学生信息的话只需要添加STUDENT_CARD索引就行了,创建一个(学号、姓名)的组合索引就会显得不合适,但是如果现在有一个高频请求,要根据学号查询他的姓名,这个联合索引就有意义了。它可以在这个高频请求上用到覆盖索引,不再需要回表查整行记录,减少语句的执行时间。如果为每一种查询都设计一个索引,索引就会显得太多。

这时候可以利用mysql的B+ 树这种索引结构,可以利用索引的“最左前缀”,来定位记录。

就比如(name,age)这个联合索引,索引示意图大概如下:

当我们使用这个sql查询(where name like ‘张 %’),然后可以用上这个索引查找到第一个符合条件的记录是 ID3,然后向后遍历,直到不满足条件为止。可以看出,只要满足最左前缀,就可以利用索引来加速检索。

索引下推

MySQL 5.6 引入的索引下推优化(index condition pushdown), 可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数。

比如使用以下sql做查询时:

select * from SCHOOL_STUDENT_INFO where name like '张%' and age=18 and ismale=1;

这时候InnoDB 在 (name,age) 索引内部就判断了 age 是否等于 18,对于不等于 18 的记录,直接判断并跳过。

你可能感兴趣的:(工作总结,java,后端)