Documentation Home
MySQL 5.6 リファレンスマニュアル
Download this Manual
PDF (US Ltr) - 20.9Mb
PDF (A4) - 21.0Mb
HTML Download (TGZ) - 7.2Mb
HTML Download (Zip) - 7.2Mb


13.2.5.1 INSERT ... SELECT 構文

INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name 
    [PARTITION (partition_name,...)]
    [(col_name,...)]
    SELECT ...
    [ ON DUPLICATE KEY UPDATE col_name=expr, ... ]

INSERT ... SELECT を使用すると、1 つまたは多数のテーブルから多数の行をテーブルにすばやく挿入できます。例:

INSERT INTO tbl_temp2 (fld_id)
  SELECT tbl_temp1.fld_order_id
  FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;

INSERT ... SELECT ステートメントには、次の条件が適用されます。

  • 重複キー違反の原因になる行を無視するには、IGNORE を指定します。

  • DELAYED は、INSERT ... SELECT では無視されます。

  • INSERT ステートメントのターゲットテーブルが、クエリーの SELECT 部分の FROM 句に現れてもかまいません。(これは、一部の古いバージョンの MySQL では不可能でした。)ただし、テーブルに挿入し、さらにサブクエリーで同じテーブルから選択することはできません。

    テーブルからの選択とそのテーブルへの挿入を同時に行う場合、MySQL は SELECT からの行を保持するための一時テーブルを作成してから、それらの行をターゲットテーブルに挿入します。ただし、TEMPORARY テーブルを同じステートメント内で 2 回参照することはできないため、tTEMPORARY テーブルのときに INSERT INTO t ... SELECT ... FROM t を使用できない点は引き続き残ります (セクションB.5.7.2「TEMPORARY テーブルに関する問題」を参照してください)。

  • AUTO_INCREMENT カラムは、通常どおりに機能します。

  • バイナリログを使用して元のテーブルを確実に再作成できるようにするために、MySQL では、INSERT ... SELECT ステートメントでの並列挿入が許可されません。

  • SELECTINSERT が同じテーブルを参照している場合のあいまいなカラム参照の問題を回避するには、SELECT 部分で使用されている各テーブルの一意のエイリアスを指定し、その部分にあるカラム名を適切なエイリアスで修飾します。

MySQL 5.6.2 からは、テーブルの名前に続く PARTITION オプションでソースまたはターゲットテーブル (またはその両方) のどのパーティションまたはサブパーティション (またはその両方) を使用するかを明示的に選択できます。PARTITION がこのステートメントの SELECT 部分にあるソーステーブルの名前とともに使用されている場合は、そのパーティションリストで指定されているパーティションまたはサブパーティションの行のみが選択されます。PARTITION がこのステートメントの INSERT 部分のターゲットテーブルの名前とともに使用されている場合は、選択されたすべての行を、このオプションに続くパーティションリストで指定されているパーティションまたはサブパーティションに挿入できる必要があります。そうでない場合、INSERT ... SELECT ステートメントは失敗します。詳細および例については、セクション19.5「パーティション選択」を参照してください。

ON DUPLICATE KEY UPDATE の値の部分では、SELECT 部分で GROUP BY を使用していないかぎり、ほかのテーブル内のカラムを参照できます。1 つの副作用として、値の部分にある一意でないカラム名を修飾しなければならない点があります。

ORDER BY 句のない SELECT ステートメントが行を返す順序は特定されていません。つまり、レプリケーションを使用している場合、このような SELECT がマスターとスレーブ上で行を同じ順序で返す保証はありません。これにより、マスターとスレーブの間で不整合が発生する場合があります。これが発生しないようにするために、レプリケートされる INSERT ... SELECT ステートメントは常に INSERT ... SELECT ... ORDER BY column として記述するようにしてください。column の選択は、マスターとスレーブの両方で間違いなく行が同じ順序で返されるかぎり問題にはなりません。セクション17.4.1.16「レプリケーションと LIMIT」も参照してください。

この問題のために、MySQL 5.6.4 から、INSERT ... SELECT ON DUPLICATE KEY UPDATE および INSERT IGNORE ... SELECT ステートメントには、ステートメントベースのレプリケーションには安全でないというフラグが付けられます。この変更により、このようなステートメントは、ステートメントベースモードを使用しているときはログ内に警告を生成し、MIXED モードを使用しているときは行ベース形式を使用してログに記録されます。(Bug #11758262、Bug #50439)

セクション17.1.2.1「ステートメントベースおよび行ベースレプリケーションのメリットとデメリット」も参照してください。

MySQL 5.6.6 より前は、テーブルレベルのロックを採用した MyISAM などのストレージエンジンを使用しているパーティション化されたテーブルに対して機能した INSERT ... SELECT ステートメントによって、ソースおよびターゲットテーブルのすべてのパーティションがロックされました。(これは、行レベルロックを採用した InnoDB などのストレージエンジンを使用しているテーブルでは発生しておらず、現在も発生しません。)MySQL 5.6.6 以降では、ターゲットテーブルのすべてのパーティションがロックされますが、ソーステーブルは実際に読み取られたパーティションのみがロックされます。詳細は、セクション19.6.4「パーティショニングとロック」を参照してください。