问:可以说说聚集索引和非聚集索引区别吗?
在Mysql中,有两大常用的存储引擎MyisAm和Innodb,Myisam使用的是非聚集索引也叫非聚簇索引,InnoDb使用的是聚集索引,聚集索引就是以主键创建的索引,非聚集索引就是除了主键以外的索引。非聚集索引在建立的时候也未必是单列的,可以多个列来创建索引,本质区别是表记录的排列顺序和索引的排列顺序是否一致。
聚集索引的叶节点就是数据节点,而非聚簇索引的叶节点仍然是索引节点,并保留一个链接指向对应数据块。
聚簇索引主键的插入速度要比非聚簇索引主键的插入速度慢很多。
相比之下,聚簇索引适合排序,非聚簇索引不适合用在排序的场合。因为聚簇索引叶节点本身就是索引和数据按相同顺序放置在一起,索引序即是数据序,数据序即是索引序,所以很快。非聚簇索引叶节点是保留了一个指向数据的指针,索引本身当然是排序的,但是数据并未排序,数据查询的时候需要消耗额外更多的I/O,所以较慢。
当你需要取出一定范围内的数据时,用聚簇索引也比用非聚簇索引好。
问:聚集索引有什么缺点?
插入速度严重依赖于插入顺序,按照主键的顺序插入是加载数据到innodb表中速度最快的方式,但如果不是按照主键顺序加载数据,那么在加载完成后最好使用optimizetable命令重新组织一下表。
更新聚集索引列的代价很高,因为会强制innodb将每个被更新的行移动到新的位置
基于聚集索引的表在插入新行,或者主键被更新导致需要移动行的时候,可能面临页分裂的问题,当行的主键值要求必须将这一行插入到某个已满的页中时,存储引擎会将该页分裂成两个页面来容纳该行,这就是一次页分裂操作,页分裂会导致表占用更多的磁盘空间
问:使用聚集索引为什么查询速度会变快?
聚簇索引对于那些经常要搜索范围值的列特别有效。使用聚簇索引找到包含第一个值的行后,便可以确保包含后续索引值的行在物理相邻。数据存储结构方面:聚簇索引的索引页面指针指向数据页面,所以使用聚簇索引查找数据总是比使用非聚簇索引快。每张表只能建一个聚簇索引,并且建聚簇索引需要至少相当该表%的附加空间,以存放该表的副本和索引中间页。
数据检索方面:在那些包含范围检查(between、、=、、=)或使用groupby或orderby的查询时,一旦找到具有范围中第一个键值的行,具有后续索引值的行保证物理上毗连在一起而不必进一步搜索,避免了大范围扫描,可以大大提高查询速度。同样,如果对从表中检索的数据进行排序时经常要用到某一列,则可以将该表在该列上聚簇(物理排序),避免每次查询该列时都进行排序,从而节省成本。
问:建立聚集索引有什么需要注意的地方吗?
在聚簇索引中不要包含经常修改的列,因为码值修改后,数据行必须移动到新的位置,索引此时会重排,会造成很大的资源浪费。
选择聚簇索引应基于where子句和连接操作的类型。
问:为什么非聚集索引会降低插入和更新速度?
每当你改变了一个建立了非聚簇索引的表中的数据时,必须同时更新索引。因此你对一个表建立非聚簇索引时要慎重考虑。如果你预计一个表需要频繁地更新数据,那么不要对它建立太多非聚簇索引。另外,如果硬盘和内存空间有限,也应该限制使用非聚簇索引的数量。
问:InnoDB引擎中数据的存储方式是什么样的?
聚集索引就是按照每张表的主键构造一颗B+树,它的叶子节点存放的是整行数据。
InnoDB的主键一定是聚集索引。如果没有定义主键,聚集索引可能是第一个不允许为null的唯一索引,也有可能是rowid。
问:InnoDB引擎索引都有哪些特征?
1.聚集索引表记录的排列顺序和索引的排列顺序保持一致,所以查询效率相当快。只要找到第一个索引记录的值,其余的连续性的记录也一定是连续存放的。
2.聚集索引的缺点就是修改起来比较版,因为它需要保持表中记录和索引的顺序需要一致,在插入新记录的时候就会对数据也重新做一次排序。
3.在数据表创建上INNODB聚集索引存储的是一个文件,后缀为.frm
4.InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。
问:InnoDB表对主键生成策略是什么样的?
优先使用用户自定义主键作为主键,如果用户没有定义主键,则选取一个Unique键作为主键,如果表中连Unique键都没有定义的话,则InnoDB会为表默认添加一个名为row_id的隐藏列作为主键。InnoDB存储引擎会为每条记录都添加transaction_id和roll_pointer这两个列,但是row_id是可选的(在没有自定义主键以及Unique键的情况下才会添加该列)。这些隐藏列的值不用我们操心,InnoDB存储引擎会自己帮我们生成的。
问:InnoDB表中为什么只能有一个聚集索引?
每个表只能有一个聚簇索引,是因为一个表中的记录只能以一种物理顺序存放,实际的数据页只能按照一颗B+树进行排序。查询优化器倾向于采用聚集索引,因为聚集索引能够在B+树索引的叶子节点上直接找到数据。聚簇索引类似于电话簿,后者按姓氏排列数据。由于聚簇索引规定数据在表中的物理存储顺序,因此一个表只能包含一个聚簇索引(TokuDB引擎除外)。汉语字典也是聚簇索引的典型应用,在汉语字典里,索引项是字母+声调,字典正文也是按照先字母再声调的顺序排列。
问:表中可以有多个非聚集索引吗?要是可以的话,最多可以有多少个?
但是,一个表可以有不止一个非聚簇索引。实际上,对每个表你最多可以建立个非聚簇索引。非聚簇索引需要大量的硬盘空间和内存。
问题:BTree与Hash索引有什么区别?
BTree索引可能需要多次运用折半查找来找到对应的数据块(对比跟节点-子树-叶子节点-数据块);而HASH索引是通过HASH函数,计算出HASH值,在表中找出对应的数据。优缺点对比:大量不同数据等值精确查询,HASH索引效率通常比B+TREE高。但是HASH索引不支持模糊查询、排序、范围查询和联合索引中的最左匹配规则,而这些Btree索引都支持。
问:InnoDB辅助索引B+树不能找到给定键值具体行,只能找的行所在页;而聚集索引存的就是主键和行的完整字段。既然都有完整字段了为什么是找不到具体行?
聚集索引树也是先找到的是数据所在的页,然后将页放入内存中,通过二分查找找到对应的行,只是这个内存查找的过程时间很短,所以很多时候我们就不提了。
这些问题等待下一章节为大家解答:
请问MyIsAm与InnoDB在索引方面都有哪些区别?
数据量相同的情况下,B树和B+树,哪个占用空间更大?