MySQL聚簇索引深入理解(2)

由上图可以看出,InnoDB 的聚簇索引的每一个叶子节点都包含了主键值、事务ID、用于事务和 MVCC 的回滚指针以及所有的剩余列(在这个例子中是 col2)。如果主键是一个列前缀索引,InnoDB 也会包含完整的主键列和剩下的其他列。

还有一点和 MyISAM 的不同是,InnoDB 的二级索引和聚簇索引很不相同。InnoDB 二级索引的叶子节点中存储的不是“行指针”,而是主键值,并以此作为指向行的“指针”。

这样的策略减少了当出现行移动或者数据页分裂时二级索引的维护工作。使用主键值当作指针会让二级索引占用更多的空间,换来的好处是,InnoDB 在移动行时无须更新二级索引中的这个“指针”。

图 5-8 可以看出表的 col2 索引,每一个叶子节点都包含了索引列(这里是 col2),紧接着是主键值(col1)。

MySQL聚簇索引深入理解

图 5-9 是描述 InnoDB 和 MyISAM 如何存放表的抽象图,可以很容易的看出 InnoDB 和 MyISAM 保存数据和索引的区别。

MySQL聚簇索引深入理解

在 InnoDB 表中按主键顺序插入行

最好避免使用随机的(不连续且值的分布范围非常大)的列做聚簇索引(可以使用 int 型的自增 ID),特别是 I/O 密集型的应用。例如:使用 UUID 来作为聚簇索引则会很糟糕:它使得聚簇索引的插入变得完全随机,这是最坏的情况,使得数据没有任何聚集特性。

下面我们用两张表来做基准测试。第一个表使用整数 ID 插入 userinfo 表:

CREATE TABLE `userinfo`(
    `id` int unsigend NOT NULL AUTO_INCREMENT,
    `name` varchar(64) NOT NULL DEFAULT '',
    `email` varchar(64) NOT NULL DEFAULT '',
    `password` varchar(64) NOT NULL DEFAULT '',
    `dob` date DEFAULT NULL,
    `address` varchar(255) NOT NULL DEFAULT '',
    `city` varchar(64) NOT NULL DEFAULT '',
    `state_id` tinyint unsigend NOT NULL DEFAULT '0',
    `country_id` smallint unsigend NOT NULL DEFAULT '0',
    PRIMARY KEY (id),
    UNIQUE  KEY email (email),
    KEY        country_id (country_id),
    KEY        state_id (state_id),
    KEY        state_id_2 (state_id,city,address)
) ENGINE = InnoDB

第二个例子是 userinfo_uuid 表,除了主键改为 UUID,其余和前面的 userinfo 表完全相同。

1 CREATE TABLE `userinfo`( 2 `uuid` varchar(36) NOT NULL, 3 ... 4 );

现在已经创建好了两个测试表了,接下来我们依次插入100万条记录。然后继续依次插入300万条记录,使索引的大小超过服务器的内存容量。结果如下图:

MySQL聚簇索引深入理解

注意到向 UUID 插入行不仅花费的时间更长,而且索引占用的空间也更大。这一方面是由于主键字段更长;另一方面是由于页分裂和碎片导致的。

图 5-10 是往第一个表插入数据时,索引发生的变化。

MySQL聚簇索引深入理解

如图 5-10 可以看出,因为主键的值是顺序的,所以 InnoDB 把每一条记录都存储在上一条记录的后面。当达到页的最大填充因子时(InnoDB 默认的最大填充因子是页大小的 15/16,留出部分空间用于以后修改),下一条记录就会写入新的页中。一旦数据按照这种顺序的方式加载,主键页就会近似于被顺序的记录填满(二级索引页可能是不一样的)。

图 5-11 是往 UUID 表插入数据时,索引发生的变化。

MySQL聚簇索引深入理解

  由图 5-11 可知,因为新行的主键值不一定比之前插入的大,所以 InnoDB 无法简单地总是把新行插入到索引的最后,而是需要给新行寻找合适的位置 —— 通常是已有数据的中间位置 —— 并且分配空间。这会增加很多的额外工作,并导致数据分布不够优化。下面是总结的一些缺点:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/53efb852187001eb40c756ba0a9c0c54.html