本文介绍: 在MySQL中存储大量的数据,那么数据如何组织能进行高效的数据库操作就显得尤为重要,那么就是帮助数据库高效获取数据的。

MySQL之索引

在MySQL中存储大量的数据,那么数据如何组织能进行高效的数据库操作就显得尤为重要,那么索引就是帮助数据库高效获取数据结构

索引优缺点

优点:

缺点:

索引的分类

根据物理存储形式划分

聚簇索引

聚簇索引可以理解为一种数据存储形式(依靠B+树实现),索引与数据存放在一起,找到索引就找到了数据;且一个表中只能有一个,如果表中存在主键那么主键索引就是聚簇索引,如果不存在主键,将使用一个唯一(UNIQUE)索引作为聚集索引;其余情况InnoDB会自动生成一个row_id作为隐藏的聚集索引。

优点:

1.查找速度快, 因为数据和索引存放在同一个B+树中,找到索引就找到了数据,省去了回表操作

2.聚簇索引对于主键的排序查找范围查找速度非常快

3.节省了大量的IO时间,因为数据在聚簇索引中排列是紧密的

缺点:

1.插入速度严重依赖插入顺序,按照主键的顺序插入是最快的,否则就会导致页分裂

2.更新主键的代价大,因此一般主键设为不可更新(因为可能设计多表关联

3.二级索引访问需要两次索引查找,第一次查找主键,第二次查找行数

非聚簇索引(二级索引)

非聚簇索引的索引和数据时是分开的,一个表中可以多个二级索引,使用二级索引查找数据总是需要二次查询(回表

聚簇索引和非聚簇索引的对比

在这里插入图片描述

1.聚簇索引存储的就是数据记录,非聚簇索引存储数据位置,非聚簇索引不会影响数据表物理存储顺序

2.一个表只能有一个聚簇索引,因为只能有一种物理存储方式;可以多个非聚簇索引,也就是多个索引目录提供检索

3.聚簇索引的查询效率优秀但更新效率低

根据逻辑功能划分

普通索引

没有限制条件用于提高查询的效率。这类索引可以添加在任何数据类型上,其值是否非空唯一由它本身完整性约束决定

唯一索引

使用UNIQUE设置唯一性索引,保证该索引的值唯一可以声明多个

主键索引

特殊的唯一性索引 UNIQUE+NOT_NULL一个表中最多只有一个主键(因为一个表只能有一种物理存储形式)

单列索引

表中的单个字段创建索引。单列字段只根据该字段进行索引,一个表中可以多个单列索引

多列索引(联合索引)

多列索引是在指索引以两个两个以上字段进行组织可以通过多个字段进行索引查询但是必须遵循最左前缀原则(即使用 where条件要按照建立索引的时候字段的排列方式放置索引才会生效

全文索引

搜索引擎使用的关键技术通过分词进行匹配

空间索引

使用SPATIAL可以设置索引为空间索引。空间索引只能建立在空间数据类型上,可以提高系统获取空间数据类型的效率。(目前只有MyISAM支持空间索引)

索引的数据结构

B-TREE

B-Tree(多路平衡搜索树)树高一层意味着多一次磁盘I/O,下图是5阶B树

在这里插入图片描述

B-树特征

B+TREE

在这里插入图片描述

B+树特征:

HASH

在这里插入图片描述

Hash索引仅仅能满足”=”,“IN”和”<=>”查询,不能使用范围查询。也不支持任何范围查询,例如WHERE price > 100。 
由于Hash索引比较的是进行Hash运算之后的Hash值,所以它只能用于等值的过滤,不能用于基于范围的过滤,因为经过相应的Hash算法处理之后的Hash值的大小关系,并不能保证和Hash运算前完全一样。

InnoDB引擎为什么选择B+索引结构

B+树相比于B树,在每个节点取消了存储的数据可以释放更多的空间来存储索引,这样构造的树结果就更矮更扁查询效率高,降低了进行IO的次数;

并且数据页间通过双向链表连接,数据页中的数据通过按照顺序组成一个单向链表,相比于Hash索引,支持区间查询以及排序操作

构造B+树结构哪些注意事项

1.根页面位置不动,在生成B+树的过程中 经过数据的添加 –>数据页的复制–>目录页–>页分裂 但根页面的位置不改变 这样的话InnoDB引擎用到这个索引的话从固定的地方取出节点的页号来访问这个索引

2.内节点目录页的唯一性,二级索引的目录项如果不添加上主键的话有可能出现不唯一的情况,如果存在太多的重复索引,那么使用索引查询的效率也会大大降低

3.一个页面至少存储两条记录

不同存储引擎索引的实现

InnoDB

InnoDB使用B+TREE存储数据,除了主键索引为聚簇索引,其它索引均为非聚簇索引。

一个表中只能存在一个聚簇索引(主键索引),但可以存在多个非聚簇索引。

InnoDB表的索引和数据是存储在一起的,.idb表数据和索引的文件

InnoDB索引优化

InnoDB中主键不宜定义太大,因为辅助索引也会包含主键列,如果主键定义比较大,其他索引也将很大。如果想在表上定义 、很多索引,则争取尽量把主键定义得小一些。InnoDB 不会压缩索引。

InnoDB中尽量不使用非单调字段作主键(不使用多列),因为InnoDB数据文件本身是一颗B+Tree,非单调的主键会造成在插入记录数据文件为了维持B+Tree的特性而频繁的分裂调整,十分低效,而使用自增字段作为主键则是一个很好的选择

MyISAM

MyISAM也使用B+Tree作为索引结构,但具体实现方式却与InnoDB截然不同。MyISAM使用的都是非聚簇索引。

MyISAM表的索引和数据是分开存储的,.MYD数据文件 .MYI表索引文件

两者索引使用的区别

1.在InnoDB中我们需要主键查找时使用聚簇索引直接就可以查找到想要的数据而MyISM只能查找到数据的地址必须进行额外的一次回表操作才能查找到数据

2.InnoDB中数据文件本身就是索引文件 而MyISAM中数据文件和索引文件是分离的

3.InnoDB中非聚簇索引的data域存储的是主键的值,而MyISAM存储的是地址

4.MyISAM直接通过地址偏移量查找效率高回表速度很快

5.InnoDB中一定要有主键而MyISAM不要求

索引的设计原则

什么情况下适合创建索引

什么情况下不适合创建索引

  • 查询频率
  • 区分度低(重复数据多)
  • 表的数据量
  • 避免对经常进行更新的字段创建索引
  • 避免冗余或重复索引

索引优化

覆盖索引

查询的字段与索引的字段相同需要回表那么就说明使用了覆盖索引

优点:

1.避免进行回表操作(InnoDB是以聚集索引存储的那么在通过二级索引进行查询数据的时,如果查询的数据包含在了索引内那么不需要进行回表

2.把随机IO变成顺序IO

缺点:

索引字段的维护是需要代价的,因此在建立冗余索引字段时需要权衡

索引下推(ICP)

一般针对联合索引,在查询时索引失效了但索引的字段包含条件那么索引下推将条件执行完再回表,进行较少回表的数据

没有使用ICP的情况下,MySQL的查询:

使用ICP的情况下,查询过程:

  • 存储引擎读取索引记录(不是完整的行记录);
  • 判断WHERE条件部分能否用索引中的列来做检查,条件不满足,则处理一行索引记录;
  • 条件满足,使用索引中的主键去定位读取完整的行记录(就是所谓的回表);
  • 存储引擎把记录交给Server层,Server检测该记录是否满足WHERE条件的其余部分。

ICP使用条件

索引失效

>、<范围查询(一般将范围查询条件放在最后)

mysql 会一直向右匹配直到遇到索引搜索键使用&gt;、<就停止匹配。一旦权重最高的索引搜索键使用>、<范围查询,那么其它>、<搜索键都无法用作索引。即索引最多使用一个>、<的范围列,因此如果查询条件中有两个>、<范围列则无法全用到索引。

like %xx

搜索键值通配符%开头(如:like '%abc'),则索引失效,直接全表扫描;若只是以%结尾,则不影响索引构建

类型转换导致索引失败

如果列是字符串类型,传入条件是必须用引号引起来,不然报错或索引失效

计算或者函数导致索引失效

如果查询条件中含有函数表达式,将导致索引失效而进行全表扫描

不等于索引失效情况

普通索引使用 !=索引失效,主键索引没影响
where语句中索引列使用了负向查询,可能会导致索引失效。
负向查询包括:NOT、!=、<>、NOT IN、NOT LIKE等。

or 条件索引问题

or 的条件列除了同时是主键的时候,索引才会生效。其他情况下的,无论条件列是什么,索引都失效。

联合索引违背最左匹配原则

联合索引中,where中索引列违背最左匹配原则,一定会导致索引失效

原文地址:https://blog.csdn.net/qq_62592925/article/details/134715910

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_16127.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注