先介绍一下Mysql中的聚集索引
在MySQL中,聚集索引(clustered index)就是主键索引,不使用主键来作为索引的就是非聚集索引。
Mysql中索引使用B+树的结构来优化查询速度和减少磁盘io次数
以下是B+树的结构
大家都应该了解二叉树和二分查找算法,Mysql为什么不使用二叉树结构而使用B+数呢?
MySQL之所以选择B+树而不是二叉树来实现索引结构,是基于以下几点考虑:
-
多路搜索:B+树是一种多路搜索树,每个节点可以存储多个索引键和数据指针。相比于二叉树每个节点只能存储两个子节点的情况,B+树的每个节点可以存储更多的键值对,减少了树的高度,从而降低了磁盘IO的次数。
-
顺序访问:B+树的叶子节点通过链表连接,形成了有序的数据集合。这使得范围查询和顺序访问非常高效,能够有效利用磁盘预读,减少磁盘IO的次数。相比之下,二叉树需要进行随机访问,无法有效利用磁盘的预读特性。
-
高度平衡:B+树通过自动调整节点的分裂和合并来保持树的平衡,保证了每个节点的高度相近。相比之下,二叉树的高度可能出现严重的不平衡,可能一边多一边少,导致查询性能下降。
总而言之,B+树在设计上是为了优化多路搜索、外存存储和顺序访问等特点。对于数据库系统来说,B+树结构更适合存储和查询大量数据时的场景,能够在保持查询性能稳定的同时,减少了磁盘IO次数,提高了数据访问的效率。因此,MySQL选择使用B+树作为索引结构,以满足数据库高效存储和查询的需求。
为什么推荐非分布式情况下选用自增id做主键而不是UUID?
在非分布式环境中,选择自增ID作为主键而不是UUID的主要原因是性能和存储空间的考虑。
-
性能:自增ID是递增的整数,通常由数据库自动生成,每次插入新记录时,只需简单地自增ID的值即可。这种简单的递增操作通常比生成UUID的算法更快。
-
存储空间:自增ID通常只占用较小的存储空间(通常是整数类型),而UUID是一个128位的全局唯一字符串。使用UUID作为主键将导致更大的存储空间需求
-
索引效率:自增ID通常在数据库索引中更加紧凑和高效,因为它们是递增的整数。相比之下,UUID是一个全局唯一的字符串,生成的字符串较长,需要更大的存储空间,并且在索引操作中消耗更多的资源。
需要注意的是,这种选择是在非分布式环境下的一般情况下的推荐做法。在分布式系统中,使用自增ID作为主键可能会导致冲突,因为不同节点生成的自增ID可能会重复。在这种情况下,使用UUID或其他全局唯一标识符可能更适合保证数据的唯一性。
综上所述,在非分布式环境中,选择自增ID作为主键而不是UUID可以提供更好的性能和节省存储空间。但在特定需求和分布式环境下,应根据具体情况进行权衡和选择。
UUID容易导致过多的叶子节点分裂
叶子节点分裂是指当叶子节点已满时,需要分裂成两个新的叶子节点来容纳新的数据。这种操作涉及到节点的分裂和索引的更新,可能导致大量的磁盘写入和索引维护操作,影响数据库的性能和吞吐量。
为了避免过多的叶子节点分裂,可以考虑采用递增的整型数据作为主键,如自增ID,而不是UUID。
我们已经了解基于B+树构建的索引,叶子节点存放了所有的通过双向链表连接的有序数据,递增的主键会使新数据向右顺序插入到B+树的叶子节点,减少了分裂的频率,不会引起叶子节点的分裂。B+树的叶子节点之间通过指针连接,形成一个有序链表,查询时可以顺着链表进行遍历,从而提高查询效率。
相比于任意顺序的主键数据,使用自增整型数据作为主键可以最大程度地减少叶子节点的分裂,从而减少了数据插入时带来的索引更新操作,提高了插入的效率。
同时,在查询操作中,由于数据按照顺序插入,可以有效利用磁盘预读,减少磁盘IO的次数,提高查询效率。