[TOC]
索引基本介绍
在任何数据库当中 主键上都会自动添加对象,另外 在mysql中一个字段如果有unique约束的话,也会创建索引对象。
在任何数据库中,任何一张表的任何一条记录在硬盘存储上都有一个硬盘的物理存储编号。
在mysql中,索引是一个单独的对象,不同的存储引擎以不同的形式存在,在 MyISAM存储引擎中,索引存储在一个 .MYI文件中。在InnoDB存储引擎中索引存储在一个逻辑名称叫做 tablespace 的当中。在 MEMORY存储引擎中索引被存储在内存中。不管索引存储在哪里,索引在mysql中都是一个树的形式存在。
mysql索引底层时BTree
什么时候添加索引?
- 数据量庞大
- 该字段经常出现在where后面,以条件的形式存在,也就是说这个字段总是被扫描
- 该字段很少的DML(insert、update、delete),因为增删改之后,索引需要重排序
- 在经常用在连接的列上,这 些列主要是一些外键,可以加快连接的速度;
- 在经常需要排序的列上创 建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;
为什么不对表中每一列都添加索引呢?
- 当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。
- 索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。
- 随着数据量的增加,索引的创建和维护消耗的时间也会增加。
索引的增删查
- 创建索引:create index 索引名 on 表名(需要添加索引的字段名)
- 删除索引:drop index 索引名 on 索引所在的表名
- 查看是否使用索引,使用 explain
注意避免冗余索引
冗余索引指的是索引的功能相同,能够命中 就肯定能命中 ,那么 就是冗余索引如(name,city )和(name )这两个索引就是冗余索引,能够命中后者的查询肯定是能够命中前者的 在大多数情况下,都应该尽量扩展已有的索引而不是创建新索引。
MySQL 5.7 版本后,可以通过查询 sys 库的 schema_redundant_indexes
表来查看冗余索引
为什么索引不用二叉树这种数据结构?
可能出现以下这种极端情况,这样一来跟没有加索引一样,即使加了索引也没用。
搞得跟单链表一样,所以不使用二叉树。
为什么索引不用红黑树这种数据结构?
如果存储的数据达到百万、千万甚至过亿级别,那么树的深度会非常大,磁盘IO次数还是多,所以不使用。
为什么mysql页文件默认为16K?
BTree
- 数据
- 向下的指针
- 指向数据的指针
B+Tree
B+Tree每个节点可以包含更多的节点,这个做的原因有两个,第一个原因是为了降低树的高度,第二个原因是将数据范围变为多个区间,区间越多,数据检索越快。
非叶子节点存储key,叶子节点存储key和数据
叶子节点两两指针相互连接,顺序查询性能更高