mysql聚簇索引和非聚簇索引的优缺点

Posted 走,我们去吹风

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql聚簇索引和非聚簇索引的优缺点相关的知识,希望对你有一定的参考价值。

mysql中的索引分为聚簇索引和非聚簇索引,它们之间的区别在于数据的存储方式不同。

1、聚簇索引

聚簇索引(Clustered Index)是一种按照列的顺序将数据存储在表中的一种方式。它是将数据行存储在同一块中,并按照索引顺序进行排序的索引。在MySQL中,每张表只能有一个聚簇索引,因为数据行只能按照一种方式进行排序。简单来说:找到了索引就找到了需要的数据,那么这个索引就是聚簇索引,所以主键就是聚簇索引,修改聚簇索引其实就是修改主键。

聚簇索引的优点:

  • 能够快速地按照索引顺序进行数据访问,因为相邻的数据行存储在同一块中,I/O操作次数更少,因此查询速度更快。
  • 聚簇索引的叶子节点存储的是数据行本身,因此对于不需要查询全部列的查询语句,能够减少I/O操作,提高查询速度。
  • 数据存储在聚簇索引中,因此能够减少磁盘的占用,提高存储效率。

聚簇索引的缺点:

  • 插入和更新数据时需要移动其他数据行,因此性能较差。
  • 数据按照索引顺序进行排序,因此可能导致某些数据访问较慢,例如按照非索引列进行查询。

2、非聚簇索引

非聚簇索引(Non-Clustered Index)是另一种将数据存储在表中的索引方式,它是将索引列的值和指向存储数据的指针一起存储在索引中的方式。在MySQL中,一张表可以有多个非聚簇索引。

非聚簇索引的优点:

  • 插入和更新数据时不需要移动其他数据行,因此性能较好。
  • 非聚簇索引能够加速数据查询,提高查询速度。

非聚簇索引的缺点:

  • 查询非索引列的时候,需要进行二次查找,因此相对于聚簇索引,查询速度较慢。
  • 非聚簇索引的叶子节点不存储数据行,因此对于需要查询全部列的查询语句,需要进行额外的I/O操作,降低查询效率。

总结:

聚簇索引适合于那些经常需要按照索引顺序进行数据查询的表,例如时间序列数据表;而非聚簇索引适合于那些需要频繁插入和更新数据的表,例如日志表。在实际使用中,应根据表的特点选择合适的索引类型。

一分钟明白MySQL聚簇索引和非聚簇索引

MySQL的InnoDB索引数据结构是B+树,主键索引叶子节点的值存储的就是MySQL的数据行,普通索引的叶子节点的值存储的是主键值,这是了解聚簇索引和非聚簇索引的前提

什么是聚簇索引?

很简单记住一句话:找到了索引就找到了需要的数据,那么这个索引就是聚簇索引,所以主键就是聚簇索引,修改聚簇索引其实就是修改主键。

什么是非聚簇索引?

索引的存储和数据的存储是分离的,也就是说找到了索引但没找到数据,需要根据索引上的值(主键)再次回表查询,非聚簇索引也叫做辅助索引。

clustered index(MySQL官方对聚簇索引的解释)

The?InnoDB?term for a?primary key?index.?InnoDB?table storage is organized based on the values of the primary key columns, to speed up queries and sorts involving the primary key columns. For best performance, choose the primary key columns carefully based on the most performance-critical queries. Because modifying the columns of the clustered index is an expensive operation, choose primary columns that are rarely or never updated.
注意标黑的那段话,聚簇索引就是主键的一种术语

一个例子

下面我们创建了一个学生表,做三种查询,来说明什么情况下是聚簇索引,什么情况下不是。

create table student (
    id bigint,
    no varchar(20) ,
    name varchar(20) ,
    address varchar(20) ,
    PRIMARY KEY (`branch_id`) USING BTREE,
    UNIQUE KEY `idx_no` (`no`) USING BTREE
)ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

第一种,直接根据主键查询获去所有字段数据,此时主键时聚簇索引,因为主键对应的索引叶子节点存储了id=1的所有字段的值。

select * from student where id = 1

第二种,根据编号查询编号和名称,编号本身是一个唯一索引,但查询的列包含了学生编号和学生名称,当命中编号索引时,该索引的节点的数据存储的是主键ID,需要根据主键ID重新查询一次,所以这种查询下no不是聚簇索引

select no,name from student where no = ‘test‘

第三种,我们根据编号查询编号(有人会问知道编号了还要查询?要,你可能需要验证该编号在数据库中是否存在),这种查询命中编号索引时,直接返回编号,因为所需要的数据就是该索引,不需要回表查询,这种场景下no是聚簇索引

select no from student where no = ‘test‘

总结

主键一定是聚簇索引,MySQL的InnoDB中一定有主键,即便研发人员不手动设置,则会使用unique索引,没有unique索引,则会使用数据库内部的一个行的id来当作主键索引,其它普通索引需要区分SQL场景,当SQL查询的列就是索引本身时,我们称这种场景下该普通索引也可以叫做聚簇索引,MyisAM引擎没有聚簇索引。


以上是关于mysql聚簇索引和非聚簇索引的优缺点的主要内容,如果未能解决你的问题,请参考以下文章

Mysql聚簇索引和非聚簇索引

MySQL 聚簇索引和非聚簇索引的认识

一分钟明白MySQL聚簇索引和非聚簇索引

一分钟明白MySQL聚簇索引和非聚簇索引

mysql索引总结-MySQL聚簇索引和非聚簇索引

MySQL聚簇索引和非聚簇索引的区别