web-dev-qa-db-ja.com

MySQL:トランザクション内でテーブルを切り捨てますか?

60kから200kのレコード内のどこかで10分ごとに再入力する必要があるInnoDBテーブルがあります。ここまでのアプローチは次のとおりです。

  1. 自動コミットをオフにする
  2. テーブルを切り捨てます
  3. 選択クエリと追加計算を実行する(PHPを使用)
  4. 新しいレコードを挿入する
  5. コミット

ただし、Truncate操作を実行すると、データはすぐに削除され、ユーザーインターフェイスから使用できなくなります。ユーザーにとっては、スクリプトが約30秒以内にコミット操作に遭遇し、テーブルが再入力されたとしても、これはかなり困惑しています。

おそらく、私はトランザクション全体でincludeTruncateをラップすることができ、これによりトランザクションを削減できると考えましたユーザーにテーブルが空であるように見える時間の長さ。だから私はSET AUTOCOMMIT=0からSTART TRANSCATION

Yikes!これは望ましい効果とは逆の効果がありました!これで、TRUNCATE操作はスクリプトの先頭で引き続き発生しますが、トランザクション内でINSERT操作を実際に実行するにははるかに長いがかかるため、 COMMIT操作が行われ、テーブル内のデータが再び利用可能になります。ほぼ10分です!

何が原因でしょうか?正直なところ、トランザクションを開始すると基本的にAutocommitがオフになるだけだと思っていたので、まったく変化を期待していませんでした。

34
Brian Lacy

これを達成するためのより良い方法は、新しいテーブルにデータを挿入し、それらを交換するために両方のテーブルで rename を使用することです。単一の名前変更はスワップに必要なすべてであり、これはアトミックアクションです。つまり、ユーザーは、新しいデータが表示されることを除いて、それが発生したことを検出することさえできません。その後、古いデータを切り捨て/削除できます。

60
Kibbee

http://dev.mysql.com/doc/refman/5.1/en/truncate-table.html

このURLによると、MySQL 5.1.32以降、TRUNCATE TABLEはDDLであり、DELETEのようなDMLではありません。この意味は TRUNCATE TABLEは、トランザクションブロックの途中で暗黙的なCOMMITを発生させます。したがって、DELETE FROMの代わりに空にする必要があるテーブルでTRUNCATE TABLE

でもDELETE FROM tblname;はロールバックできます。ロールバックにはしばらく時間がかかる可能性があるため、このようなロールバックの可能性があるトランザクション時間を処理するようにInnoDBが適切に調整されていることを確認してください。

64
RolandoMySQLDBA

あなたの説明から私はあなたの時差を本当に説明することはできません。頭に浮かぶ唯一のことは、実際に挿入をoneトランザクションにラップするのではなく、ループするということです。

SET AUTOCOMMIT = 0との主な違いは、すでに0の場合、何も実行されないことです。STARTTRANSACTIONと同様に、現在のトランザクション内でサブトランザクションを開始します。

0
Mel