【问题标题】:MySQL: is out-of-order inserts into PK B+ Tree slower than out-of-order inserts into Secondary Index B+ Tree?MySQL:无序插入 PK B+ 树是否比无序插入二级索引 B+ 树慢?
【发布时间】:2011-07-24 19:51:36
【问题描述】:

在 MySQL 中使用自动增量 PK 的主要原因之一是它保证所有插入到聚集 PK 索引中的操作都是有序的,因此速度很快。我明白了。

但是二级索引呢?假设我的表有一个二级索引。插入相对于 PK 聚集索引是有序的,但相对于二级索引 B+ 树是无序的。

那么插入会不会仍然很慢,因为 MySQL 需要在插入时不断重新排列二级索引 B+ 树?

我只是想知道在这里使用自动增量是否真的能在插入性能方面给我带来任何好处。非常感谢这里的一些澄清。

【问题讨论】:

标签: mysql database-design insert auto-increment clustered-index


【解决方案1】:

主键会被聚簇,也就是说它直接指向磁盘上的数据。必须重新排列这些数据意味着必须移动完整的记录。对于二级索引,它实际上只是一堆指向磁盘位置的指针。二级索引与记录的顺序无关,因此必须在二级索引中移动指针就是移动指针。这比移动完整记录要快得多。

【讨论】:

    【解决方案2】:

    只有当你有一个只写(或至少只更新)表时,你的基本假设才成立。如果您要删除记录,则新记录的 PK 将不按顺序(物理)插入。

    索引插入的效率几乎总是次要考虑因素,而将其搞乱是一种过早的优化反模式。您是否考虑过基数、键字段长度、缓存大小等通常更重要的问题?

    首先,使用自动增量代理 PK 通常不是最理想的 - 通常有一个更有用的唯一键,其具有以更有意义的方式聚集的真实值。 (而且你只能使用 innodb 表进行集群——你意识到了,对吧?)


    “聚类”意味着索引本质上是表。所以在插入代理键时它有一个好处,因为所有内容都会添加到表的末尾,因为下一个索引值总是高于任何前一个索引值(正如您已经知道的那样。)

    除非您要填补已删除记录造成的漏洞。这可能会间接发生,但可能是一个开销问题,因为必须重新定位整个记录,这显然比仅移动索引键值和指针要多。

    集群记录对于单个记录的查询并没有像对记录范围(例如,订单、客户、用户的项目)的查询提供太多好处。如果您可以为例如,对于同一用户,值得对其进行聚类。为单个用户连续插入记录的可能性要小得多(在大多数情况下),因此按时间顺序进行聚类并没有多大帮助。但您的要求可能会有所不同。


    您没有指定 innodb,所以我主要回答 myisam(默认),其中只有自动增量或按时间顺序索引可以模拟集群 - 没有明确的选项。

    【讨论】:

    • 即使删除,就 PK 而言,所有新插入仍然是有序的。并且使用自动增量代理 PK 并不是“通常是次优的”。事实上,InnoDB(该公司)建议使用自动增量 PK。
    猜你喜欢
    • 2012-01-18
    • 2012-04-10
    • 2021-08-27
    • 1970-01-01
    • 1970-01-01
    • 2013-04-10
    • 2016-03-02
    • 2011-05-20
    相关资源
    最近更新 更多