文章目录

  • 什么是索引
  • 索引的优缺点
  • MySQL中的索引
  • 单列索引
  • 组合索引
  • 全文索引
  • 空间索引
  • innoDB存储下的索引分类
  • 回表查询
  • 添加索引的SQL语句
  • 索引的数据结构
  • 索引提高速度原理
  • 最左前缀原则
  • 注意事项


什么是索引

索引是一种用于快速查询和检索数据的数据结构。
mysql中的索引结构有: B+树和Hash。
索引相当于目录的作用,使查找更加迅速

索引的优缺点

优点

  1. 通过减少索引的数据量来加快索引的检索速度。
  2. 通过索引对数据进行排序,降低数据排序成本,减少cpu消耗。

缺点

  1. 创建和维护索引需要耗费额外时间,使更新表的时候会变慢。
  2. 占用物理存储空间。

MySQL中的索引

单列索引

单列索引中包含普通、唯一、主键、前缀这四个索引。一个索引只包含一个列,但一个表中可以有多个单列索引。

  1. 普通索引
    普通索引的唯一作用:快速查询数据。
    一张表允许创建多个普通索引,允许数据重复与 NULL。
  2. 唯一索引
    索引列中的值必须是唯一的,但是可以为空值。
  3. 主键索引
    特殊的唯一索引,不允许有空值。
  4. 前缀索引
    前缀索引只适用于字符串类型的数据。
    前缀索引是对文本的前几个字符创建索引,相比于普通索引建立的数据更小,因为只取前几个字符。

组合索引

在表中的多个字段组合上创建的索引。
只有在查询条件中使用了这些字段的左边字段时,才会调用索引。组合索引遵循最左前缀集合。

全文索引

为了检索大文本数据中的关键字信息,是目前搜索引擎数据库使用的一种技术。

空间索引

对空间数据类型的字段建立的索引。使用SPATIAL关键字。
空间数据类型:GEOMETRY POINT LINESTRING POLYGON

innoDB存储下的索引分类

分类

含义

特点

聚集索引(Clustered Index)

将数据存储与索引放在一起,索引结构的叶子节点保存了行数据

有且仅有一个

二级索引(Secondary Index)

将数据与索引分开存储,索引结构的叶子节点关联的是对应的主键

可以有多个

聚集索引选取原则:

  • 如果存在主键,主键索引为聚集索引
  • 如果不存在主键,将使用第一个唯一索引
  • 如果表没有主键,或没有合适的唯一索引,自动生成一个rowid作为隐藏的聚集索引。

回表查询

由于数据 innodb 底层是 b+ 树实现的, 所以查询的时候会通过二叉树的查找模式来进行查找。b+ 树的每个叶子节点都会存放数据,而二级索引存放的是这行数据的id值, 所以拿到 id 后,需要在查找一下聚集索引。聚集索引的叶子节点存放的是这行数据的所有信息.。
这个行为也称为:回表查询

添加索引的SQL语句

  1. 主键索引 - PRIMARY KEY
ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )
  1. 唯一索引 - UNIQUE
ALTER TABLE `table_name` ADD UNIQUE ( `column` )
  1. 普通索引 - INDEX
ALTER TABLE `table_name` ADD INDEX index_name ( `column` )
  1. 全文索引 - FULLTEXT
ALTER TABLE `table_name` ADD FULLTEXT ( `column`)
  1. 多列索引
ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )

索引的数据结构

  1. 哈希索引
    对于哈希索引来说,底层的数据结构就是哈希表,因此在绝大多数需求为单条记录查询的时候,可以选择哈希索引,查询性能最快;其余大部分场景,建议选择BTree索引。
  2. BTree树索引
    是一种很普遍的数据库索引结构。其特点是定位高效、利用率高、自我平衡,理论上,使用Btree在亿条数据与100条数据中定位记录的花销相同。

索引提高速度原理

mysql的存储形式是页, 在没有使用索引时:

  1. 定位到记录所在的页:需要遍历双向链表,找到所在的页;
  2. 从所在的页内中查找相应的记录:由于不是根据主键查询,只能遍历所在页的单链表了,这种查找时间复杂度为数据库唯一索引冲突java报错 唯一索引数据结构_主键

当添加索引后::将无序的数据变成有序(相对),通过 “目录” 就可以很快地定位到对应的页上(二分查找,时间复杂度近似为数据库唯一索引冲突java报错 唯一索引数据结构_数据_02

最左前缀原则

如 User 表的namecity加联合索引就是(name,city),而最左前缀原则指的是,如果查询的时候查询条件精确匹配索引的左边连续一列或几列,则此列就可以被用到。如下:

select * from user where name=xx and city=xx ; // 可以命中索引
select * from user where name=xx ; // 可以命中索引
select * from user where city=xx ; // 无法命中索引

例如组合索引数据库唯一索引冲突java报错 唯一索引数据结构_主键_03,组合索引的生效原则是

从前往后依次使用生效,如果中间某个索引没有使用,那么断点前面的索引部分起作用,断点后面的索引没有起作用;

比如

  • where a=3 and b=45 and c=5 这种三个索引顺序使用中间没有断点,全部发挥作用;
  • where a=3 and c=5 这种情况下数据库唯一索引冲突java报错 唯一索引数据结构_数据_04就是断点,数据库唯一索引冲突java报错 唯一索引数据结构_mysql_05发挥了效果,数据库唯一索引冲突java报错 唯一索引数据结构_主键_06没有效果;
  • where b=3 and c=4 这种情况下数据库唯一索引冲突java报错 唯一索引数据结构_mysql_05就是断点,在数据库唯一索引冲突java报错 唯一索引数据结构_mysql_05后面的索引都没有发挥作用,这种写法联合索引没有发挥任何效果;
  • where b=45 and a=3 and c=5 这个跟第一个一样,全部发挥作用,数据库唯一索引冲突java报错 唯一索引数据结构_数据_09只要用上了就行,跟写的顺序无关

注意事项

  1. 经常需要搜索的列上,可以加快搜索的速度;
  2. 在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。
  3. 在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;
  4. 对于中到大型表索引都是非常有效的,但是特大型表的话维护开销会很大,不适合建索引。
  5. 在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度;
  6. 避免 where 子句中对宇段施加函数,这会造成无法命中索引。
  7. 在使用 InnoDB 时使用与业务无关的自增主键作为主键,即使用逻辑主键,而不要使用业务主键。
  8. 删除长期未使用的索引