2

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

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

在第一个测试中,升序是 PRIMARY KEY,(random_1random_2)是 KEY。在第二个测试中,( random_1 , random_2 ) 是 PRIMARY KEY 并且升序是 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%。任何人都可以推测为什么?

4

1 回答 1

2

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

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

更新

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

于 2013-03-11T21:08:37.033 回答