Si je veux INSERT
une ligne uniquement si la clé primaire n'existe pas encore, est-il plus efficace/plus simple d'exécuter INSERT
directement et d'ignorer l'erreur en cas de duplication, ou devrait je lance toujours SELECT
pour vérifier s'il existe déjà en premier?
Vous pouvez utiliser WHERE NOT EXISTS pour vérifier les nouvelles valeurs avant d'insérer un nouvel enregistrement.
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);
Cet enregistrement existe et ne doit pas être inséré:
INSERT INTO foo (id, v1, v2) SELECT 1, 101, 101 FROM dual WHERE NOT EXISTS (SELECT 1 FROM foo WHERE id=1);
Voici un nouveau record:
INSERT INTO foo (id, v1, v2) SELECT 3, 300, 300 FROM dual WHERE NOT EXISTS (SELECT 1 FROM foo WHERE id=3);
Le résultat final:
SELECT * FROM foo;
id | v1 | v2 -: | -: | -: 1 | 100 | 100 2 | 200 | 200 3 | 300 | 300
dbfiddle ici
La meilleure option (plus efficace) dépendra de la probabilité attendue de collision PK.
Si le risque de collision est élevé, je sauverais la surcharge DML et ferais le SELECT
d'abord avant le potentiel INSERT
.
Si le risque de collision est rare, il suffit probablement de faire un INSERT IGNORE
.
Remarque: si le PK est un auto_increment
, un échec INSERT IGNORE
peut potentiellement gonfler le auto_increment
(voir innodb_autoinc_lock_mode pour les options variables).
En général, IODKU est la meilleure façon:
INSERT INTO tbl ...
ON DUPLICATE KEY UPDATE
....
https://dev.mysql.com/doc/refman/5.6/en/insert-on-duplicate.html