主キーがまだ存在しない場合にのみ行をINSERT
したい場合、INSERT
を直接実行して、重複の場合にエラーを無視する方が効率的/簡単ですか、または私は常にSELECT
を実行して、最初にすでに存在するかどうかを確認しますか?
WHERE NOT EXISTSを使用して、新しいレコードを挿入する前に新しい値を確認できます。
INSERT INTO <table>
(
field1, field2, field3
)
SELECT value1, value2, value3
FROM dual
WHERE NOT EXISTS (SELECT 1
FROM <table>
WHERE <pk fields> = <new values>);
CREATE TABLE foo(id int, v1 int, v2 int); INSERT INTO foo VALUES (1, 100,100); INSERT INTO foo VALUES (2, 200, 200);
このレコードは存在するため、挿入しないでください:
INSERT INTO foo (id, v1, v2) SELECT 1, 101, 101 FROM dual WHERE NOT EXISTS (SELECT 1 FROM foo WHERE id=1);
これは新しいレコードです。
INSERT INTO foo (id, v1, v2) SELECT 3, 300, 300 FROM dual WHERE NOT EXISTS (SELECT 1 FROM foo WHERE id=3);
最終結果:
SELECT * FROM foo;
id | v1 | v2 -:| -:| -: 1 | 100 | 100 2 | 200 | 200 3 | 300 | 300
dbfiddle ここ
最良(より効率的なオプション)は、PK衝突の予想される確率に依存します。
衝突の可能性が高い場合は、DMLオーバーヘッドを節約し、SELECT
の前に最初にINSERT
を実行します。
衝突する可能性が低い場合は、INSERT IGNORE
を実行するだけで十分です。
注:PKがauto_increment
の場合、失敗したINSERT IGNORE
はauto_increment
を膨らませる可能性があります(変数オプションについては innodb_autoinc_lock_mode を参照)。
通常、IODKUがより良い方法です。
INSERT INTO tbl ...
ON DUPLICATE KEY UPDATE
....
https://dev.mysql.com/doc/refman/5.6/en/insert-on-duplicate.html