web-dev-qa-db-ja.com

テーブルの複数のキーを削除する

テーブルに複数のKEYSをドロップするのが望ましいオプションですか、それとも1つずつ優先するのですか?

「ドロップキーA、ドロップキーB、ドロップキーC」

テーブル内の9億件を超えるレコード。

内部ではどのように機能しますか?

6
Mannoj

1つのSQLコマンドで複数のインデックスをすべて削除する方がはるかに優れています。どうして ?

シナリオ#1

ALTER TABLE mytable DROP INDEX ndx1;
ALTER TABLE mytable DROP INDEX ndx2;
ALTER TABLE mytable DROP INDEX ndx3;

これが起こります

  • 空の一時テーブルを作成します
  • 空の一時テーブルからインデックスを削除します
  • データを一時テーブルにコピーします
  • 一時テーブルを元のテーブルと交換します
  • 元のテーブルを削除します

#SCENARIO #1では、これは3回発生します。

シナリオ#2

ALTER TABLE mytable
    DROP INDEX ndx1,
    DROP INDEX ndx2,
    DROP INDEX ndx3
;

MySQLは、MySQL 4.1の下で2006年に3回この変換を使用していたと思いますか?つまり、SCENARIO #2SCENARIO #1のように処理されます。私は実際に、MySQL ABの一般ディスカッションフォーラムに投稿して、これを変更するようリクエストしました( なぜmysqlは大きなテーブルでインデックスを非常に遅くするのですか? )。

誰かがDBA StackExchangeでMySQLがまだこれを行っているかどうか尋ねました。私はここに投稿しましたが、これはもう当てはまりません( MySQLはまだこのようにインデックスを処理していますか? )。その質問は 私の元のMySQL AB投稿 を参照しています。

MySQLが今日行うことは次のとおりです。

  • 一時テーブルを作成します
  • 空の一時テーブルに対して3つのALTER TABLEコマンドを実行します
  • データを一時テーブルに一度コピーします
  • 一時テーブルを元のテーブルと交換します
  • 元のテーブルを削除します

したがって、MySQLが今日正しく動作することを信頼できます。

SCENARIO #2を使用する必要があります。

試してみる !!!

UPDATE 2015-01-02 13:06 EST

あなたがたずねた

テーブルに対する新しい操作はどうなりますか?コピー時に新しいレコードはどこに保存されますか?テーブルロックまたはメタデータロックのどちらを使用しますか?

テーブルは常にロックされます。もちろん、SCENARIO #1SCENARIO #2の3倍の時間ロックされます。このためにダウンタイムをとることができない場合、選択肢は pt-online-schema-change の1つだけです。 INSERT、UPDATE、DELETEはすべて、変更中に適切に処理されます。

UPDATE 2015-01-03 08:33 EST

@ eroomydnaがコメントを投稿しました

@ rolando、dev.mysql.com/doc/refman/5.5/en/innodb-create-index.htmlの影響を考慮した場合、5.6のデフォルトです。上記のグループ化されたddlを使用してテーブルを再構築しないでください。この操作にpt-oscを使用する必要はありません。

@eroomydnaはこれを指摘するのが正しいです。彼が提供したURLはこれについての洞察を与えてくれます。

あなたの特定の質問については、@ eroomydnaは pt-online-schema-change は必要ないと言っていますが、3つのインデックスを削除しているので、この場合は彼が正しいです。 高速インデックス作成の実装の詳細、段落2 に注意してください。

セカンダリインデックスの削除は簡単です。内部のInnoDBシステムテーブルとMySQLデータディクショナリテーブルのみが更新され、インデックスが存在しないという事実が反映されます。 InnoDBは、インデックスに使用されたストレージを、それが含まれるテーブルスペースに返します。これにより、新しいインデックスまたは追加のテーブル行がスペースを使用できるようになります。

9億のテーブルがあり、おそらく3つのインデックスに対して多数のインデックスページがあります。インデックスの削除は論理的な方法で行われており、スペースを再利用できるようにするには、これらのページをすべて無効にする必要があります。これにより、読み取りと書き込みのブロックを可能にする多くの共有ロックも作成されます。したがって、この操作は比較的高速です。どれだけ時間がかかるかわかりません。ダウンタイムを取ることはできないと述べたので、多数の共有ロックとブロックされた書き込みがあるライブテーブルでは、数秒、数分、場合によっては数時間になる可能性があります。

DEVサーバーまたはテストサーバーにテーブルのコピーがある場合は、DROP KEY A,DROP KEY B,DROP KEY Cを実行して、実行速度を確認します。次に、ダウンタイムがそれだけの価値があるかどうかを検討できます。それでも、テーブルを稼働させたいが実際にダウンタイムを実行できない場合は、 pt-online-schema-change を使用する必要があります。

私の答えについては、それは

  • インデックスを削除し、同じ名前のインデックスを作成する
  • pRIMARY KEYのドロップ/追加
9
RolandoMySQLDBA