mysql的聚集索引和非聚集索引
前几天做了一个面试,从优化数据库谈到索引,最后问了我聚集索引和非聚集索引的问题。当时那个叫悔恨啊,平时学习mysql索引这方便的知识,也都看到了这样的字眼,,但总的来说只是大概了解了相应的知识,大体上浏览一遍,没有深入去理解,今天抽时间专门来学习学习。
mysql 中不同的索引引擎对索引的实现方式不同,最常用的是MyISAM和InnoDB两种存储引擎
MyISAM 的B+ Tree的叶子节点上的data并不是数据本身,而是数据的存放地址。所以物理存储上MyISAM引擎的表会有三个文件(表结构文件,数据文件,索引文件)。
InnoDB的数据文件本身就是索引文件,B+Tree的叶子节点上的data就是数据本身,key为主键,这是聚簇索引,聚簇索引一张表是唯一的,不然表的数据存储的顺序就乱了(就是说innodb表只能有一个主键)。
一、二者的区别
1.聚集索引一个表只能有一个,而非聚集索引一个表可以存在多个。(因为这个聚簇索引的顺序就决定了数据的顺序)
2.聚集索引存储记录是物理上连续存在,而非聚集索引是逻辑上的连续,物理存储并不连续。
3.聚集索引查询数据速度快,插入数据速度慢;非聚集索引反之。
聚集索引表记录的排列顺序与索引的排列顺序一致,优点是查询速度快,因为一旦具有第一个索引值的纪录被找到,具有连续索引值的记录也一定物理的紧跟其后。
聚集索引的缺点是对表进行修改速度较慢,这是为了保持表中的记录的物理顺序与索引的顺序一致,而把记录插入到数据页的相应位置,必须在数据页中进行数据重排,降低了执行速度。插入数据时速度要慢(时间花费在“物理存储的排序”上,也就是首先要找到位置然后插入)。
非聚集索引指定了表中记录的逻辑顺序,但记录的物理顺序和索引的顺序不一致,聚集索引和非聚集索引都采用了B+树的结构,但非聚集索引的叶子层并不与实际的数据页相重叠,而采用叶子层包含一个指向表中的记录在数据页中的指针的方式。非聚集索引比聚集索引层次多,添加记录不会引起数据顺序的重组。
索引是通过二叉树的数据结构来描述的,我们可以这么理解聚簇索引:索引的叶节点就是数据节点。而非聚簇索引的叶节点仍然是索引节点,只不过有一个指针指向对应的数据块。