MySQL 5.1 リファレンスマニュアル :: 12 SQL ステートメント構文 :: 12.2 データ取り扱いステートメント :: 12.2.4 INSERT 構文 :: 12.2.4.2 INSERT DELAYED 構文
« 12.2.4.1 INSERT ... SELECT 構文

12.2.4.3 INSERT ... ON DUPLICATE KEY UPDATE 構文 »
Section Navigation      [Toggle]
  • 12.2.4 INSERT 構文
  • 12.2.4.1 INSERT ... SELECT 構文
  • 12.2.4.2 INSERT DELAYED 構文
  • 12.2.4.3 INSERT ... ON DUPLICATE KEY UPDATE 構文

12.2.4.2. INSERT DELAYED 構文

INSERT DELAYED ...

INSERT ステートメントの DELAYED オプションは、もし INSERT が完了するのを待つ事ができない、または待つ必要がないクライアントを持っている場合に大変有効となる、スタンダード SQL の MySQL 拡張子です。これは、MySQL をログに利用し、完了までに長時間かかる SELECT と UPDATE ステートメントを定期的に起動させる時によく起こる状態です。

クライアントが INSERT DELAYED を利用する時、サーバからすぐに OK が出て、テーブルが別のスレッドによって使用中でなければ行が挿入される為にキューを作ります。

INSERT DELAYED を利用する事のそれ以外の大きな利益は、たくさんのクライアントからの挿入は一緒にまとめられ、ひとつのブロックに書き込まれると言う事です。これは、別々の挿入を何度も行うよりも早く機能します。

INSERT DELAYED は、もしテーブルが他の形で利用されていないのであれば、通常の INSERT よりも遅いという事に注意してください。また、サーバには、遅れている行を持つ各テーブルに別々のスレッドを扱う為の、追加オーバーヘッドもあります。これは、本当に INSERT DELAYED が必要だという事が確実な時だけ利用するべきであるという事を意味します。

キューを作った行は、テーブルに挿入されるまでメモリ内だけで保持されます。これは、もしmysqld を強制的に終了させたり (例えば、kill -9 を利用して)、mysqld が突然停止してしまったりすると、ディスクに書き込まれる前のキューを作った行は全て失われてしまう という事を意味します。

DELAYED の利用に関しては、いくつかの制限があります。

  • INSERT DELAYED は MyISAM、MEMORY、そして ARCHIVE テーブルとのみ機能します。項13.4. 「MyISAM ストレージエンジン」、項13.7. 「MEMORY (HEAP) ストレージエンジン」、そして 項13.10. 「ARCHIVE ストレージエンジン」 を参照してください。

    もしデータファイル中にフリー ブロックがなければ、MyISAM テーブルには並列 SELECT と INSERT ステートメントがサポートされます。これらの条件下では、INSERT DELAYED を MyISAM と一緒に利用しなければいけない事はほとんどありません。

  • INSERT DELAYED は、値リストを指定する INSERT ステートメントにだけ利用されなければいけません。サーバは、INSERT ... SELECT か INSERT ... ON DUPLICATE KEY UPDATE に対して DELAYED を無視します。

  • INSERT DELAYED ステートメントがすぐに返されるので、そのステートメントが生成するであろう AUTO_INCREMENT 値を得る為に、行が挿入される前に、LAST_INSERT_ID() を利用する事はできません。

  • DELAYED 行は、実際に挿入されるまでは SELECT ステートメントには見えません。

  • DELAYED は、スレーブにマスタとは異なるデータを持たせる事があるので、スレーブ複製サーバ上では無視されます。

  • テーブルが書き込みロックされ、ALTER TABLE がテーブル構造を変更するのに利用されると、保留中の INSERT DELAYED ステートメントは失われてしまいます。

  • INSERT DELAYED は画面をサポートしません。

次に、INSERT や REPLACE に DELAYED を利用した時に何が起こるかを詳しく説明しています。この説明の中では、「スレッド」 は INSERT DELAYED ステートメントを受け取ったスレッドで、「ハンドラ」 は特定のテーブルの為に全ての INSERT DELAYED ステートメントを扱うスレッドを表しています。

  • スレッドが DELAYED ステートメントをテーブルに実行した時、もし同じようなハンドラが既に存在していなければ、全ての DELAYED ステートメントをテーブルに生成する為にハンドラ スレッドが作成されます。

  • スレッドは、ハンドラが以前に DELAYED ロックを習得したかどうかを確認します。もし習得していなければ、ハンドラ スレッドに対して習得するよう命令します。もし他のスレッドが READ か WRITE ロックをテーブル上に持っていても、DELAYED ロックを得る事ができます。しかし、ハンドラはテーブル構造が最新であるかどうかを確認する為に、全ての ALTER TABLE ロックや FLUSH TABLES ステートメントが終了するのを待ちます。

  • スレッドは INSERT ステートメントを実行しますが、行をテーブルに書き込む代わりに、ハンドラ スレッドに管理されているキューに最終行のコピーを置きます。構文エラーは全てスレッドに見つけられ、クライアント プログラムにリポートされます。

  • クライアントは、挿入操作が完了する前に INSERT が返る為、複製行の数や、結果として生じる行の AUTO_INCREMENT 値をサーバから得る事ができません。(もし C API を利用すると、同じ理由で mysql_info() 関数からは意味のある答えが返りません。)

  • 行がテーブルに挿入された時、バイナリ ログはハンドラ スレッドによって更新されます。複合行挿入の場合、最初の行が挿入された時にバイナリ ログが更新されます。

  • delayed_insert_limit 行が書かれる度に、ハンドラはまだ保留中の SELECT ステートメントがないかどうかを確認します。もしあれば、続ける前にそれらを実行させます。

  • ハンドラのキューに行が無くなると、テーブルのロックは外されます。もし新しい INSERT DELAYED ステートメントが delayed_insert_timeout 秒以内に受信されたら、ハンドラは終了します。

  • もし delayed_queue_size 以上の行が、特定のハンドラ キューの中で保留中だったら、 INSERT DELAYED をリクエストしているスレッドは、キューの中にスペースができるまで待ちます。これは、遅れたメモリのキューの為に mysqld が全てのメモリを使わない事を保障する為に行われます。

  • ハンドラスレッドは、Command カラム内の delayed_insert と共に、MySQL プロセス リスト内に現れます。これは、もし FLUSH TABLES ステートメントを実行したり、KILL thread_id を利用したりすると中止されます。しかし、終了する前にまずテーブル内でキューを作っている全ての行を格納します。この最中は、別のスレッドから新しい INSERT ステートメントを受け入れません。もしこの後に INSERT DELAYED ステートメントを実行すると、新しいハンドラ スレッドが作成されます。

    もし起動中の INSERT DELAYED ハンドラがあったら、INSERT DELAYED ステートメントは通常の INSERT ステートメントより高い優先権を持つという事を意味します。その他の更新ステートメントは、INSERT DELAYED キューが空になるか、誰かがハンドラスレッドを終了させるか (KILL thread_id を利用して)、誰かが FLUSH TABLES を実行するまで待たなければいけません。

  • 次の状態変数は INSERT DELAYED ステートメントの情報を提供します。

    状態変数 意味
    Delayed_insert_threads ハンドラ スレッド数
    Delayed_writes INSERT DELAYED で書かれた行数
    Not_flushed_delayed_rows 書き込みを待つ行数

    SHOW STATUS ステートメントか、mysqladmin extended-status コマンドを実行する事でこれらの変数を見る事ができます。

Copyright © 1997, 2010, Oracle and/or its affiliates. All rights reserved. Legal Notices
Top / Previous / Next / Up / Table of Contents
© 2010, Oracle Corporation and/or its affiliates