MySQL 04 深入浅出索引(上)
<h3 id="索引的常见模型">索引的常见模型</h3><p>实现索引的方式有很多种,这里先介绍三种常见结构:哈希表、有序数组和搜索树。</p>
<p>哈希表:只适用于<strong>只有等值查询</strong>的场景。</p>
<p>有序数组:在等值查询和范围查询场景中的性能都非常优秀,但是在更新数据的时候需要挪动大量记录。因此,只适用于<strong>静态存储引擎</strong>。</p>
<p>二叉搜索树:树层数可能很高,可能一个节点上的数据在一个物理数据块上,那么访问叶子节点的数据需要大量磁盘IO。</p>
<p>为了让一个查询尽量少进行磁盘IO,使用N叉树代替二叉树。</p>
<p>数据库技术发展至今,跳表、LSM树等结构也被用于引擎设计中。需要明白的是,数据库底层存储的核心就基于数据模型,因此每碰到一个新数据库,需要先关注它的数据模型,这样才能从理论上分析出这个数据库的适用场景。</p>
<h3 id="innodb的索引模型">InnoDB的索引模型</h3>
<p>在InnoDB中,表都是根据主键顺序以索引的形式存放的。由于InnoDB使用了B+树索引模型,所以数据都是存储在B+树中的。</p>
<p>每一个索引在InnoDB里对应一棵B+树。</p>
<p>根据叶子节点的内容,索引类型分为主键索引和非主键索引:</p>
<ul>
<li>
<p>主键索引的叶子结点存的是整行数据。在InnoDB里,主键索引也被称为聚簇索引。</p>
</li>
<li>
<p>非主键索引的叶子结点存的是主键的值。在InnoDB里,非主键索引也被称为二级索引。</p>
</li>
</ul>
<p>对于非主键索引,假设查询<code>select *</code>,那么需要先查询非主键的索引树,得到主键后再查询一次,这个过程称为<strong>回表</strong>。因此,应该尽量使用主键查询。</p>
<h3 id="索引维护">索引维护</h3>
<p>B+树为了维护索引有序性,在插入新值时候需要做必要的维护。如果插入时所在的数据页已满,根据B+树的算法,这时候需要申请一个新的数据页,然后挪动部分数据过去,这个过程称为<strong>页分裂</strong>,会对性能造成较大影响。同时,页分裂还影响数据页的利用率,原本放在一个页的数据,分到两个页中,整体空间利用率降低大约50%。</p>
<p>页分裂的逆过程为<strong>页合并</strong>。当相邻两个页由于删除了数据,利用率很低之后,会将数据页做合并。</p>
<p>基于索引维护,讨论哪些场景应该使用<strong>自增主键</strong>,哪些情况不应该用。</p>
<p>当我们设置了自增主键,插入时可以不指定主键值,且插入符合递增插入,每次插入都是一次追加操作,不会挪动其他记录,也不会触发叶子结点的分裂。而以有业务逻辑的字段做主键,往往保证不了有序插入,这样就可能有页分裂。</p>
<p>除了考虑性能,从存储空间的角度来看,自增主键的字节数也往往较小,那么普通索引的叶子节点就会越小,占用的空间也会越小。</p>
<p>因此,从<strong>性能和存储空间</strong>角度,自增主键往往是更合理的选择。而有些业务场景,比如要求只有一个唯一索引,那么该索引列自然作为主键了。</p><br><br>
来源:https://www.cnblogs.com/san-mu/p/18967212
頁:
[1]