零 困惑
当被问到查询该怎么优化时,经常脱口而出的就是加索引,那索引为啥那么牛逼呢,就能变快呢,会不会影响到其他的呢?下面就说说数据库的索引。
一 数据库穿件索引的几种方式?
1 copy table
这个是最初期的方式,创建一个临时表,把数据都copy到临时表上,然后删除原来的表再给临时表改名为之前的表,这个创建过程中表是可读的但是会多消耗一倍的空间
2 inplace
这种方式不用新建表,直接在原表上加索引,过程中表是可读的,但是不可写
3 Online
这种方式也是在原表上直接加索引,过程中即可度也可写,但是写的操作是先记录在一个文件中,等加完索引一起修改数据
二 那索引是什么?
其实索引是一种数据结构,主要包含两个,一个是B树,一个是B+树
B树和B+树的区别
B+树只有叶子节点才会存储数据,所以他的空间复杂度是log(n)
B树是每一个节点都会存储数据,而他存储数据是key value的形式
B+树的范围扫描是更快的,因为他的值都是相邻的,而B树就不行了,因为他存储的是key value形式
innodb引擎使用的是B+树的索引结构
三 索引的种类
1 聚簇索引
聚簇索引对于一个表只有一个,他就是主键,聚簇索引会改变数据的存储为一个平衡树,也就是B+树,相应的也会带来一个问题,如果对数据进行删除和新增,那么为了维持一个B+树就要移动位置,这样就增加了插入删除的时间。
2 非聚簇索引
这个就是常规索引,他也是一个平衡树,每次为一个字段加一个索引,就会新增加一个独立的索引结构,占用磁盘的空间
2 他们之间的区别
通过聚簇索引查询数据,就是直接查到需要查找的数据,而通过非聚簇索引查询,会先查询到需要查询字段的id,再通过聚簇索引查询数据,所以说聚簇索引查询的就更慢一些
3 覆盖索引
SQL只需要通过索引就可以返回查询所需要的数据,而不必通过非聚簇索引索引查到主键之后再去查询数据。 这个覆盖索引更倾向与一个实现
比如查询一个字段,这个字段没在索引列上,但是查询条件是索引,那么他的流程是,先根据非聚簇索引查询出主键索引,再根据主键回表查询相应的聚簇索引,这样就要执行两次,但是如果查询条件本身在索引范围内,那么就只需要查询一次就可以了,所以这个时候联合索引就派上了用处。
而是用联合索引需要注意一个问题,就是他只会对联合索引列中最左边的列索引有效,举个栗子,声明一个有a,b,c字段组成的联合索引,查询条件的顺序是a b c 那么走这个联合索引,如果查询条件是b a c 那么是不会走联合索引的,因为这个联合索引的数据结构就是以a b c 来建立的,