0
点赞
收藏
分享

微信扫一扫

对于MySQL表建索引的一些基本的了解

暮晨夜雪 2022-04-18 阅读 84
sql

索引的作用

    索引是帮助MySQL高效获取数据的数据结构。当表中的数据量越来越大时,索引对于性能的影响愈发重要,索引能够轻易将查询性能提高好几个数量级。

   MySQL中存储的索引类型有两张:B-TREE 和 HASH,当存储引擎是MyISAM和InnoDB时,都至此支持B-TREE,MMEORY/HEAP存储引擎是B-TREE和HASH索引都支持。本文只探讨InnoDB引擎下的B-TREE索引。

索引的分类

根据索引的具体用途,MySQL 中的索引在逻辑上分为以下 5 类:

1) 普通索引

    普通索引是 MySQL 中最基本的索引类型,它没有任何限制,唯一任务就是加快系统对数据的访问速度。普通索引允许在定义索引的列中插入重复值和空值。创建普通索引时,通常使用的关键字是 INDEX 或 KEY。

    例如:CREATE INDEX index_id ON tb_student(id);

2) 唯一索引

    唯一索引与普通索引类似,不同的是创建唯一性索引的目的不是为了提高访问速度,而是为了避免数据出现重复。唯一索引列的值必须唯一,允许有空值。如果是组合索引,则列值的组合必须唯一。创建唯一索引通常使用 UNIQUE 关键字。

    例如:CREATE UNIQUE INDEX index_id ON tb_student(id);

3) 主键索引

    顾名思义,主键索引就是专门为主键字段创建的索引,也属于索引的一种。主键索引是一种特殊的唯一索引,不允许值重复或者值为空。创建主键索引通常使用 PRIMARY KEY 关键字。不能使用 CREATE INDEX 语句创建主键索引。

    例如:PRIMARY KEY(id)

4) 空间索引

    空间索引是对空间数据类型的字段建立的索引,使用 SPATIAL 关键字进行扩展。创建空间索引的列必须将其声明为 NOT NULL,空间索引只能在存储引擎为 MyISAM 的表中创建。空间索引主要用于地理空间数据类型 GEOMETRY。对于初学者来说,这类索引很少会用到。

    例如:CREATE SPATIAL INDEX index_line ON tb_student(line);

5) 全文索引

    全文索引主要用来查找文本中的关键字,只能在 CHAR、VARCHAR 或 TEXT 类型的列上创建。在 MySQL 中只有 MyISAM 存储引擎支持全文索引。全文索引允许在索引列中插入重复值和空值。不过对于大容量的数据表,生成全文索引非常消耗时间和硬盘空间。(个人觉得全文索引还是用ElasticSearch比较靠谱...)。创建全文索引使用 FULLTEXT 关键字。

    例如:CREATE FULLTEXT INDEX index_info ON tb_student(info);

索引是越多越好么?

    并不是,索引的数目不是越多越好。每个索引都会占用磁盘空间,索引越多,需要的磁盘空间就越大。修改表时,对索引的重构和更新就很麻烦。越多的索引,会是个更新表变得非常费时。

    而且一次查询中一般都只会使用一个索引,不会使用多个索引。网上看到的说法,MySQL5.0之后貌似可以在一定的条件下使用多个索引,但是一般情况下全表扫描/只使用一个索引的速度会比去分析两个索引二叉树效率更高一些,所以绝大部分情况下数据库都是使用一个索引。

InnDB中索引的结构:

    InnoDB使用B+数来存储索引数据。结构如下:

    InnoDB 是必须要有主键的,没有设置主键也会默认生成一个可不见的主键,因为InnoDB主索引是存储方式是聚集索引,它的每个叶子节点存储了具体一行的数据信息。而由于机械硬盘的预读机制,所以一般推荐主键使用自增ID,这样能够保证数据存储的连续性。如果主键是自己设置的字段,可能东写一下西写一下,会造成很多的磁盘碎片。

    除了主键索引外,InnoDB的非主键索引数据结构如下所示。非聚集索引叶子节点存储的不是数据,而是主键值:

回表:

    回表的概念就是先通过非主键索引查询到数据索引的行的主键,然后在通过主键索引树把完整的数据提取出来。这个查询的过程设计到了两颗索引树,而且最终要返回到主索引树进行数据的提取,这个返回主索引树再查找的过程称之为回表。

    如果可以的话,应该尽量使用主键索引来查询记录,但是主键索引一般是自增ID,所以不太现实。这个时候可以考虑通过构建联合索引的方式来提供某些查询的执行效率。

联合索引:

    MySQL的单个索引中,如果索引了多个列,这个索引就叫联合索引。例如:create index lh_suoyin on my_table(a,b,c)。相当于创建了三个索引:index(a);index(a,b); index(a,b,c)。如果select条件中要获取的只是a,b,c三个字段的话,那就不需要回表了。

    联合索引除了减少回表之外,还有一个很重要的目的就是减少索引的个数,比如像上面那样物理上只有1个索引,但是逻辑上是创建了三个索引。但是联合索引在使用时有一个最左匹配原则,即查询条件中使用了联合索引左边的字段时,索引才会被使用。例如where条件中是 a=? 或者 a=?and b=?,那就走联合索引,如果是 b=? and c=?,就不能走联合索引查询。

如何合理的使用索引:

    1. where条件存在隐式类型转换或者对字段使用函数的时候,无法使用索引

    2. or条件两个字段必须都是用了索引,查询时才会使用索引

    3. 通配符查找时无法使用索引,例如 where name like '%mike'

    4. 联合索引当遇到范围查询(>、<、between、like)就会停止匹配

    5. 经常检索、排序、分组的列建议创建索引。如果列很少用于检索 或者 值大部分都是重复的 或者 是TEXT之类的长字符串类型,不建议创建索引

    差不多就到这吧,因为目前的业务场景下MySQL用的并不需要很深入,以上这些点对于目前的我来说差不多也够用了,哈哈哈,MySQL就先到这里吧。

参考:

    http://c.biancheng.net/view/7897.html(MySQL索引分类)

    https://segmentfault.com/q/1010000003880137(MySQL一般每次都只用一个索引)

    https://cloud.tencent.com/developer/article/1774781(MySQL的最左匹配原则)

举报

相关推荐

0 条评论