web-dev-qa-db-ja.com

GUID vs自動インクリメント挿入パフォーマンス

大量のデータを含むテーブルで、自動インクリメント整数とGUID(v4)の間の挿入のパフォーマンスをテストしています。これに続く ブログ投稿 、私は違いが出てくることを期待していました。しかし、現在は600万行を超えるため、違いはありません。これらは私のテーブルの定義です:

自動増加

CREATE TABLE `auto` (
    `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (`id`))

GUID

CREATE TABLE `guid` (
`id` CHAR(32) NOT NULL,
PRIMARY KEY (`id`))

コードは参照先のブログ投稿と同じで、1つのトランザクションに10万行を数回挿入します。以前に600万行を超える行で述べたように、パフォーマンスに違いはなく、実際には同じです。私はその理由を理解しようとしています。スクリプトはC#yにあり、GUIDはアプリケーションで生成されています(MySqlではありません)。より明確にするために、1から1Mまでのforループは、 DBに挿入し、10万行に達するたびにトランザクションをコミットし、コミット時の経過時間を測定します。

私のハードウェア:Mac mini i5 2.3 GHz、16 GB Ram、960 GB SSD、ただしスクリプトはWindows 10 x64の4 GBのRAMを備えたFusion仮想マシンで実行されています、仮想マシンにインストールされているMySqlサーバー。

MySqlバージョン:5.7

だから、私は何かが足りないのですか?さらにデータが必要ですか?.

前もって感謝します。

2
RenkoSmith

不足しているのは、innodb_buffer_pool_sizeの設定(InnoDBを使用している場合)、およびidのインデックスのサイズとの比較です。必要な「より多くのデータ」:

SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
SHOW TABLE STATUS LIKE 'guid';
  • idAUTO_INCREMENTまたは何らかの「増加」タイムスタンプの場合、すべての作業はインデックスの「最後の」ブロックで行われます。したがって、I/Oを回避するためにキャッシュする必要はほとんどありません。

  • idがuuid/guid/md5/etcの場合、使用されるキャッシュスペース(buffer_pool)はテーブルが大きくなるにつれて大きくなります。これは、IDが「ランダムに」ジャンプしているためです。パフォーマンスに大きな影響はありませんntil buffer_poolは十分な大きさではありません。その後、物事は徐々にファンを襲った。

さらに物を運びましょう... 100万のエントリを保持できるbuffer_poolがあるとしましょう。ただし、20Mのエントリがあります。次の行が挿入される場合、1M/20Mの確率で、目的のブロックが現在buffer_poolにキャッシュされています。つまり、わずか5%です。または、「ミス」の可能性は95%です。ほとんどの場合、ディスクヒットが必要です。 I/Oは、SQLが遅くなる主な原因です。

詳細な議論: http://mysql.rjweb.org/doc.php/uuid

結論:hugeテーブルがある場合、それがPRIMARY KEYであろうと他のインデックスであろうと、guidsはパフォーマンスを低下させます。

2
Rick James