2

MySQL 5.6 を使用して、行を空のテーブルに挿入する比較を実行しました。

各テーブルには、AUTO_INCREMENT によって連続的にインクリメントされる列 (昇順) と、ランダムで一意の番号を受け取る列のペア ( random_1random_2 ) が含まれていました。

最初のテストでは、昇順が PRIMARY KEY で、( random_1 , random_2 ) が KEY でした。2 番目のテストでは、( 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 
   ;

一貫して、2 番目のテスト (自動インクリメント列が PRIMARY KEY ではない場合) はわずかに速く実行されます (5 ~ 6%)。その理由を推測できる人はいますか?

4

1 に答える 1

2

主キーは、データが実際に保存されるシーケンスとしてよく使用されます。主キーがインクリメントされる場合、データは単に追加されます。主キーがランダムである場合、それは、新しい行を適切な順序にするために既存のデータを移動する必要があることを意味します。基本的な(主キーではない)インデックスは、通常、コンテンツがはるかに軽く、オーバーヘッドを抑えて高速に移動できます。

私はこれが他のDBMSにも当てはまることを知っています。私は、MySQLがこの点で同様に機能すると思い切って推測します。

アップデート

以下のコメントで@BillKarwinが述べているように、この理論はMyISAMテーブルには当てはまりません。フォローアップ理論として、以下の@KevinPostlewaiteの回答(彼は削除されました)を参照します。問題は、主キーにAUTO_INCREMENTがないことです。これは一意である必要があります。AUTO_INCREMENTを使用すると、値が増分であることが保証されているため、値が一意であるかどうかを簡単に判断できます。ランダムな値の場合、この決定を行うために実際にインデックスをウォークするのに時間がかかる場合があります。

于 2013-03-11T21:08:37.033 に答える