【问题标题】:MySQL performance using AUTO_INCREMENT on a PRIMARY KEY在 PRIMARY KEY 上使用 AUTO_INCREMENT 的 MySQL 性能
【发布时间】:2013-03-11 21:03:44
【问题描述】:

我使用 MySQL 5.6 运行比较 INSERTing 行到一个空表中。

每个表都包含一个按 AUTO_INCREMENT 顺序递增的列(ascending)和一对列(random_1random_2)接收随机的、唯一的数字。

在第一个测试中,ascending 是 PRIMARY KEY,(random_1, random_2) 是 KEY。在第二个测试中,(random_1, random_2) 是 PRIMARY KEY,ascending 是 KEY。

CREATE TABLE clh_test_pk_auto_increment (
   ascending_pk       BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, -- PK
   random_ak_1        BIGINT UNSIGNED NOT NULL,                -- AK1
   random_ak_2        BIGINT UNSIGNED,                         -- AK2
   payload            VARCHAR(40),
   PRIMARY KEY        ( ascending_pk ),
   KEY                ( random_ak_1, random_ak_2 )
)  ENGINE=MYISAM 
   AUTO_INCREMENT=1 
   ;

CREATE TABLE clh_test_auto_increment (
   ascending_ak       BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, -- AK
   random_pk_1        BIGINT UNSIGNED NOT NULL,                -- PK1
   random_pk_2        BIGINT UNSIGNED,                         -- PK2
   payload            VARCHAR(40),
   PRIMARY KEY        ( random_pk_1, random_pk_2 ),
   KEY                ( ascending_ak )
)  ENGINE=MYISAM 
   AUTO_INCREMENT=1 
   ;

始终如一地,第二个测试(其中自动增量列不是 PRIMARY KEY)运行速度稍快——5-6%。任何人都可以推测为什么?

【问题讨论】:

  • 我可以推测,但在您告诉我们“测试”是什么之前,这样做几乎没有意义。
  • 尽快插入 100 万行。
  • 我认为第二个测试不会像您认为的那样。看到这个:dba.stackexchange.com/questions/3467/…
  • 你为什么这么认为?一些评论指出 AUTO_INCREMENT 确实适用于非 PK(我的测试证明了这一点)。至于“为什么?”,我们有几个需要完成的大量连接,一个以 升序 顺序与另一个表连接,一个以 随机 顺序与一个表连接(不是真的随机,而是按照升序随机)。

标签: mysql primary-key auto-increment


【解决方案1】:

主键通常用作数据实际存储的顺序。如果主键增加,则简单地追加数据。如果主键是随机的,这意味着必须移动现有数据以使新行进入正确的序列。基本(非主键)索引的内容通常要轻得多,并且可以以更少的开销更快地移动。

我知道其他 DBMS 也是如此;我大胆猜测 MySQL 在这方面的工作方式类似。

更新

正如@BillKarwin 在下面的 cmets 中所述,这个理论不适用于 MyISAM 表。作为后续理论,我会参考下面@KevinPostlewaite 的答案(他已被删除),问题是主键上缺少 AUTO_INCREMENT - 这必须是唯一的。使用 AUTO_INCREMENT 更容易确定这些值是唯一的,因为它们保证是增量的。对于随机值,实际遍历索引可能需要一些时间才能做出此决定。

【讨论】:

  • 不在 MyISAM 存储引擎中;主键和辅助键没有区别。
  • 主要是隐式唯一的,次要 - 至少在这个测试中 - 没有这样声明。
  • @BillKarwin - MyISAM 引擎不聚集在主键上吗? here 提出了一个类似的答案,假设正在对主键进行聚类...
  • 对; MyISAM 不支持聚集索引。主索引和二级索引都存储在 .MYI 文件中。数据按存储顺序存储在 .MYD 文件中。如果您总是 INSERT,则 .MYD 文件包含按插入顺序排列的行。但是当您更新和删除数据时,空间将被重新分配,并且行将变得乱序存储。请参阅我对How Data is ordered in MySql by Default的回答
  • 但是您的描述对于 InnoDB 是正确的。每个 InnoDB 表都存储为主键上的聚集索引。因此,在 InnoDB 中使用升序自动增量主键有一个(小)优势——新行被附加到聚集索引的右端。
猜你喜欢
  • 1970-01-01
  • 2019-04-14
  • 1970-01-01
  • 1970-01-01
  • 2011-04-20
  • 2012-06-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多