索引 是一种数据结构
目的是帮助mysql 高效获取数据。
![](https://i-blog.csdnimg.cn/direct/633b6d94c5c646299da6dbdeeb2a89bd.png)
![](https://i-blog.csdnimg.cn/direct/09633a57d2984d589f074e0d8e76939a.png)
![](https://i-blog.csdnimg.cn/direct/63f318883e28437b99f19f9f40884abe.png)
索引结构 - 二叉树,红黑树,Btree,B+tree,mysql B+tree
因此不同的存储引擎 会有不同的 索引结构
![](https://i-blog.csdnimg.cn/direct/93fa1f6bdf50486c84c53e1157e069af.png)
![](https://i-blog.csdnimg.cn/direct/4b3a39d5026e471c86c03c127ed065fd.png)
![](https://i-blog.csdnimg.cn/direct/447d8a5788dd4c399a67cd940bb3e2c5.png)
二叉树 和 红黑树 的缺点,
![](https://i-blog.csdnimg.cn/direct/41626ce8ee5b47a188b91bbcb728f3aa.png)
Btree 的缺点
![](https://i-blog.csdnimg.cn/direct/f2309c58c6cf43948d347c611a871b9c.png)
![](https://i-blog.csdnimg.cn/direct/21426be5a33340cf921a1d2a17eb6bab.png)
引出的 B+tree
![](https://i-blog.csdnimg.cn/direct/609d2a7f73814e4688ad371714398428.png)
![](https://i-blog.csdnimg.cn/direct/e358263e66f845e29722159c03e2fc8a.png)
mysql中的B+ tree,对于一般的B+tree 有提升
![](https://i-blog.csdnimg.cn/direct/e13f1c968d384597a2dba34fe2d44fb3.png)
索引结构 -- hash
![](https://i-blog.csdnimg.cn/direct/1b3eff249fa846cc94df217c6088021e.png)
![](https://i-blog.csdnimg.cn/direct/7ce7f7c281c94b1f99c679b94a2f5bc5.png)
面试相关:为什么InnoDB存储引擎选择使用B+tree 索引机构?
![](https://i-blog.csdnimg.cn/direct/0947569cac7f4f65a66e06b96959e42f.png)
索引分类
![](https://i-blog.csdnimg.cn/direct/84f857befef54ac6bbaff1815234b01f.png)
在innoDB 存储引擎中,索引的存储方式
![](https://i-blog.csdnimg.cn/direct/81f1da21651a4a23b8790c6821da74d3.png)
在innoDB 下,聚集索引 和 二级索引 到底如何存放
![](https://i-blog.csdnimg.cn/direct/528c05aa5d9b4934bfbf9bc116a26b6d.png)
在innoDB 下,如何通过 聚集索引 和 二级索引 查询数据
我们要通过 select * from user where name = 'Arm'; 查找数据
由于 聚集索引 只能 通过id 查找,因此第一步,我们要通过二级索引 查找 id
通过二级索引查找到id后,在通过聚集索引找到 row,row就是保存的具体的一行数据。
这个过程 叫做 回表查询
![](https://i-blog.csdnimg.cn/direct/eace8333b85d4fbfa3ea6d37e72d47f3.png)
思考题
![](https://i-blog.csdnimg.cn/direct/911fe6c362b94f288816ea7022af9385.png)
对于 select * from user where id = 10;
查询聚集索引一次就可以找到
![](https://i-blog.csdnimg.cn/direct/05c753e9f42248209c2d5654c7844f53.png)
对于 select * from user where name = 'Arm';
第一步,我们要通过二级索引 查找 id
通过二级索引查找到id后,在通过聚集索引找到 row,row就是保存的具体的一行数据
要查找两次索引。
![](https://i-blog.csdnimg.cn/direct/eace8333b85d4fbfa3ea6d37e72d47f3.png)
结论:因此第一个执行效率高
思考题2:InnoDB 主键索引的B+ tree 高度为多高呢?
![](https://i-blog.csdnimg.cn/direct/44d627409be54613aa4def0680811725.png)
要看懂这个 思考题,需要结合前面的 innoDB 的逻辑存储结构一起看
第一个要弄清楚的问题:节点 是放在页中的。
一个节点是存储在 页中的,而 innoDB 一个页的大小为 16K,
换算成字节就是 一个页的大小为 16 * 1024 个字节
那么如果不是叶子节点,一个页能存储多少 键值 和 指针 呢?
对于主键索引,键值 就是我们 的主键的数据类型,int 占用4字节,bigint占用8字节,
innoDB中指针占用 6个字节。
因此对于 非叶子结点,可以存储的 键值 和 指针 大小为:
n * 8 + (n+1)*6 = 16 * 1024; n为键值,n+1 为指针,n计算出来为1170.
即 可以存放的 键值 有1170个,指针为1171个。
如果高度为2,那么 1171 个指针,就会指向 1171个页,而这些页中存放着 叶子结点。
那么1个页 存放多少个叶子结点呢?这里只有假设了,一个页还是 16k,我们假设一行数据大小为1k,那么16k的大小就能放 16 行数据。因此得出 :
1171个页 * 16 行/页 = 18736 行 数据
如果高度是3,
1171 * 1171个页 * 16 行/页 = 21939856行 数据
![](https://i-blog.csdnimg.cn/direct/19f260a4cc5d453bb32a652e01e7a085.png)
索引语法
从前面学习到的知识我们了解到,即使我们在create table的时候没有加上索引,mysql会给我们默认的加上索引,那么为什么我们还要学习 索引的语法呢?---为了效率。
如果我们想要优化 sql 语句的执行效率,就需要结合自己创建的 索引 。因此要学习 索引的语法
创建索引
create [unique | fulltext] index index_name on table_name (index_col_name,...);
unique:代表的唯一的,代表该字段是不能重复的,该字段指的是 index_col_name。 或者 index_col_name...
fulltext 代表的是 全文索引,在MySQL中,FULLTEXT
索引主要用于加速对文本数据的全文搜索。这种索引类型特别适用于那些需要快速查找包含特定单词或短语的记录的场景。例如,在博客平台中搜索文章标题或内容时,FULLTEXT
索引能够显著提高查询效率
index 代表是创建的是 索引
index_name 是我们给 这个索引起的名字
on tablename 是对于那张表
(index_col_name,...) 是我们对于 表中的那个字段建立的索引,有可能是多个字段联合起来创建的索引,如果只有一个字段名字,则叫做单列索引,如果有多个字段组成的,则叫做 组合索引 ,或者 联合索引
查看索引
show index from table_name;
删除索引
drop index index_name on table_name;
index_name: 是我们在create index 时候起的名字