2016-07-07 6 views
1

コンテキスト:私は非常に頻繁に行を挿入/更新するマルチスレッドアプリケーションを作成しています。しかし、私はMySQLは時間(source)でこれらのテーブルを更新するために一つだけのセッションを許可MyISAMテーブル用のテーブルレベルのロックを使用することがわかったいくつかの研究を行った後MyISAMとクイックインサートのためのInnoDBと複合ユニークキー

#TABLE 1 
CREATE TABLE `example` (
    `id` BIGINT(20) NOT NULL, 
    `state` VARCHAR(45) NOT NULL, 
    PRIMARY KEY (`id`, `state`)) 
ENGINE = MyISAM; 

は、もともと私は、次の表を持っていました。テーブルを頻繁に変更するマルチスレッドアプリケーションには適していません。

このように、複合主キーから、id/stateの一意のインデックスを持つ自動生成プライマリキーに切り替えることをお勧めします。これにより、ID /状態の固有の組み合わせを強制しながら、迅速な挿入が可能になります。

#TABLE 2 
CREATE TABLE `example` (
    `key` BIGINT(20) NOT NULL, 
    `id` BIGINT(20) NOT NULL, 
    `state` VARCHAR(45) NOT NULL, 
    PRIMARY KEY (`key`), 
    UNIQUE INDEX `ID_STATE` (`id` ASC, `state` ASC)) 
ENGINE = MyISAM; 

InnoDBがしかし、テーブルロックを回避し、代わりに、行レベルロック(source)を使用するので、私は以下に切り替えると考える:

#TABLE 3 
CREATE TABLE `example` (
    `key` BIGINT(20) NOT NULL, 
    `id` BIGINT(20) NOT NULL, 
    `state` VARCHAR(45) NOT NULL, 
    PRIMARY KEY (`key`), 
    UNIQUE INDEX `ID_STATE` (`id` ASC, `state` ASC)) 
ENGINE = InnoDB; 

しかし、InnoDBの周りアップ読んだ後、私はInnoDBが編成発見クラスタ化インデックスとセカンダリインデックスを使用するデータは、複数のルックアップを必要とします。 1つはセカンダリインデックス用、もう1つはプライマリキー用(source)です。そのように私は次のように切り替えて議論しています:

#TABLE 4 
CREATE TABLE `example` (
    `id` BIGINT(20) NOT NULL, 
    `state` VARCHAR(45) NOT NULL, 
    PRIMARY KEY (`id`, `state`)) 
ENGINE = InnoDB; 

をすべての私の仮定が正しければ、私は思ったんだけど:

  1. MyISAMテーブルは、挿入、更新のためにテーブル全体をロックし、そしてのみ許可DELETES 1回にこれらのテーブルを更新するセッション
  2. InnoDBは、MyISAMよりも速い複合主キーを持つINSERTを処理します。これは、InnoDBはMyISAMとは異なり、新しい主キーをスキャンして予約するためにテーブル全体をロックしないためです。
  3. InnoDBを使用している場合は、セカンダリインデックスに複数のルックアップが必要なため、複合ユニークインデックスではなく複合プライマリキーを作成する必要があります。
  4. I表4
+0

(2)は*非連続*です。 – EJP

+0

あなたが正しいです、私はそれが私が意味したことをより明確にするために更新しました。 – Rawr

答えて

3

1 - はい、2 - はい、3 - はい、4 - はいを使用すべきです。また

...

  • あなたは本当にBIGINTが必要ですか? INT UNSIGNEDには40億の価値はないでしょうか?おそらくidは他のテーブルのPKですか?もしそうなら、そのテーブルも変更する必要があります。
  • stateを正規化することはできますか?またはENUMに変更しましたか?もう一度スペースを節約する。

項目3は、2つの一意のキーをロックする必要があるため、前述したよりも悪いです。

+0

"あなたが言及したよりも悪い"という意味を明確にすることはできますか?コンポジットセカンダリインデックスを作成するには、2つ以上のルックアップが必要ですか? P.S.それらすべての良い点。私は 'BIGINT(10)'が100億で、 'INT UNSIGNED'が40億であるとは考えませんでした。 – Rawr

+0

「BIGINT」は64ビットの数字で、「+/- 8億億」です。 '(10)'は_nothing_と言う。 –

関連する問題