JAVA数据库之索引

索引

什么是索引

索引是一种特殊的数据库结构,由数据表中的一列或多列组合而成,通俗地讲,索引就像是目录,可以用来快速查询数据表中有某一特定值的记录


image.png

索引的优缺点

优点

索引可以大大提升查询的速度

缺点

时间方面
牺牲了增删改的速度,在增删改的时候需要为了保证索引的有序性,需要动态维护索引
空间上
创建索引回占用更多的物理磁盘空间

举例

image.png

我们搜索500万条数据用时2.8秒


image.png

不使用索引搜索符合条件的数据用时3.7秒


image.png

给id_code字段添加索引后的查询速度,可以看到是大大提高了

索引的类型

image.png

添加主键约束就是添加主键索引,唯一索引也是如此
主键索引 primary key,一个表只能有一个主键索引
唯一索引 unique,一个表允许多个唯一索引
普通索引(非唯一) index
全文索引 fulltext innoDB不支持
单列索引就是一个列创建的索引,组合索引的意思是多个列联合创建索引

索引的创建和删除

(聚簇索引是表自带的不允许创建)
如果没有主键,那么会选择隐藏列rowid创建聚簇索引

索引创建语法:1.create table建表的时候创建索引

2.建表成功后用alter语句添加索引
ALTER TABLE table_name ADD INDEX index_name (column_list);
3.建表成功后用create index添加索引
CREATE INDEX index_name ON table_name (column_list);

索引删除语法

1.使用alter语句删除索引
alter table 表名 drop index 索引名`
2.使用drop语句删除索引
drop index 索引名 on 表名

索引的数据结构

数据结构演进
https://www.cs.usfca.edu/~galles/visualization/Algorithms.html
数据结构演示图

二叉树

问题:无法自平衡


image.png

平衡二叉树(AVL树)

左旋算法:右边的叶子结点深度减去左边叶子结点的深度大于1的时候,触发左旋
右旋算法:左边的叶子结点深度减去右边叶子结点的深度大于1的时候,触发右旋
目的就是维持树的平衡


image.png

image.png

多路平衡二叉树 --B树

树的度数:每个节点中可以存储的元素的个数
单路数:度数=1
多路数:度数=n,n>1
同等规模的数据,单路树是高瘦的,多路树是矮胖的
多路树的优势是更少次数的磁盘IO就能找到数据


image.png

image.png

MySQL的数据结构

B+树结构索引(默认)
Hash结构索引
树的每一个节点是一个磁盘块,MySQL将表的ibd文件拆分成很多个磁盘块
磁盘块大小统一是16kb,每次磁盘IO都是读取一个磁盘块的数据
一个磁盘块的数据也称为一页数据
从B树升级为B+树

那么B树和B+树又有什么区别

image.png

1.B+树的最底层的叶子结点组成了一个单向链表
2.B+树的部分元素有冗余
3.B+树只有最底层的叶子结点才存储数据,上层所有节点只存储主键ID
4.B树行数据与主键存储在一起

走索引就是二分查找,不走索引就是全表扫描

聚簇索引和非聚簇索引

聚簇索引=主键索引=一级索引
非聚簇索引=(唯一索引、普通索引)=二级索引
除了主键索引是聚簇索引,其他所有使用非主键字段创建的索引都是非聚簇索引

索引覆盖,索引下推

索引覆盖在上面我们已经介绍了。由上面的介绍我们知道,建立了联合索引后,直接在索引中就可以得到查询结果,从而不需要回表查询聚簇索引中的行数据信息。

索引覆盖可以带来很多的好处:

辅助索引不包含行数据的所有信息,故其大小远小于聚簇索引,因此可以减少大量的IO操作。
索引覆盖只需要扫描一次索引树,不需要回表扫描聚簇索引树,所以性能比回表查询要高。
索引中列值是按顺序存储的,索引覆盖能避免范围查询回表带来的大量随机IO操作。 判断一条语句是否用到索引覆盖:

索引下推是索引下推是 MySQL 5.6 及以上版本上推出的,用于对查询进行优化。

索引下推是把本应该在 server 层进行筛选的条件,下推到存储引擎层来进行筛选判断,这样能有效减少回表

回表查询,最左前缀原则

回表查询,实际查询两次,通过辅助索引(普通索引)实现的。因为辅助索引叶子节点不存放记录数据,只存放普通值和对应记录主键值。
这就是回表查询,先定位主键值,再定位行记录,它的性能较扫一遍索引树更低,应为两次查找Tree,磁盘IO较多。
最左匹配原则:在通过联合索引检索数据时,从索引中最左边的列开始,一直向右匹配,如果遇到范围查询(>、<、between、like等),就停止后边的匹配。


image.png

image.png

无索引反而更快,这是因为有索引的情况下需要进行回表查询
因此索引并不是越多越好
数据离散度越低,越适合用索引(10%~15%,最好就是对唯一属性添加索引)

索引失效

1.不满足最左前缀原则
2.使用了函数
3.条件中使用了!=或者is not null
4.用了左模糊和全模糊 %aaaa和%aaaa%

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容