1.前言
这次小编准备用两篇文章来和大家分享下mysql innodb的索引: mysql的基础知识 和 基于索引的sql优化 。
2. 什么是索引?
定义:索引是数据库中用于快速查找数据的机制,本质是某种数据结构。它存储着指向数据的指针,从而帮助数据库跳过不必要的行,直接定位到目标数据,减少扫描时间。
比如我们看<<三国演义>>刘备三顾茅庐这章,如果没有目录,我们就需要一篇一篇的翻书,要翻很久,因为不知道在书的哪一页;但是如果有目录,我们是不是先在目录里面找到这章的目录,这章的目录对应着正文的书页,我们一下就可以翻到对应的书页,找到对应的章节。目录就类似于mysql的索引。
3. 为什么需要索引?
WHERE 子句中的条件过滤。
ORDER BY 语句进行排序时。
GROUP BY 语句进行分组时。
多表 JOIN 操作时匹配外键或其他相关列。
4. 索引的类型
5. 索引的结构
这里强调一下:innodb只能创建B-Tree 索引,不支持哈希索引。即使创建的时候选择的是哈希,实际创建之后的结果也是B-Tree,有兴趣的同学可以试试,小编这里就不截图了。
下面,小编用六条数据模拟下索引的结构。首先看下表结构:
然后表里面的数据:
然后看下主键索引的结构,这里是小编根据索引的结构自己画的:
根据这个B+ 树索引结构图,小编简单的说下:
二级索引
除了主键外,我们会根据查询的字段,也去建立相应的字段索引。小编这里就不画图了,二级索引的叶子节点放的是对应的主键索引值。
回表
指的是 MySQL 在通过二级索引查找到符合条件的记录后,还需要回到主键索引中去读取额外的列数据。因为索引只包含部分列的信息,如果查询中请求了索引中未包含的列,数据库就需要从主键索引中再次读取完整的行数据。
比如user表中,我给name添加索引,我需要查询name=小九这行数据的信息,因为二级索引是没有完整的数据,所以mysql需要去主键索引里面找到对应的完整数据返回。
覆盖索引
指的是当一个索引完全包含了查询所需的所有列时,MySQL 不需要再回表,而是直接从索引中就可以返回结果。这种情况就称为覆盖索引。
比如user表中,我给name添加索引,我需要查询name=小九这条数据的id,因为id在叶子节点已经有了,直接就返回了结果,不需要去主键索引再次查询。
覆盖索引的优势:
性能提升:避免了回表,降低了 I/O 和查询时间。减少表扫描:索引的存储比表的数据量小得多,索引扫描比全表扫描快。