¿Qué patrón de SQL es más rápido para evitar insert filas duplicadas?

Sé de dos maneras de insert sin duplicación. El primero es usar una cláusula WHERE NOT EXISTS :

 INSERT INTO table_name (col1, col2, col3) SELECT %s, %s, %s WHERE NOT EXISTS ( SELECT * FROM table_name AS T WHERE T.col1 = %s AND T.col2 = %s) 

el otro está haciendo una LEFT JOIN :

 INSERT INTO table_name (col1, col2, col3) SELECT %s, %s, %s FROM ( SELECT %s, %s, %s ) A LEFT JOIN table_name B ON B.COL1 = %s AND B.COL2 = %s WHERE B.id IS NULL LIMIT 1 

¿Existe una regla general que indique que uno es más rápido que el otro o depende de las tablas? ¿Hay alguna manera diferente que sea mejor que ambas?

Yo recomendaría definir una restricción ÚNICA en las columnas que necesita para ser único (col1 y col2 en este caso), y luego simplemente hacer el INSERTAR. Maneje excepciones según sea necesario.


Con respecto a la exception que exige una reversión, la solución para PostgreSQL es establecer un punto de almacenamiento de la transacción antes de probar la inserción que puede causar una exception. Si obtiene la exception, vuelva al punto de rescate.

Ver:

¡Creo que usar EXISTS es más eficiente! Podrías hacer esto:

 if exists(select 1 from table_name where col1 = %s and col2 = %s) then insert into table_name (col1, col2, col3) select %s, %s, %s; end if; 

bajo testing, usar EXISTS es aproximadamente 50 veces más rápido que usar NOT EXISTS.

otro método está usando EXCEPTO.

 INSERT INTO table_name (col1, col2, col3) SELECT %s, %s, %s except select col1, col2, col3 from table_name 

bajo testing, usar EXCEPT es aproximadamente 3 veces más rápido que usar NOT EXISTS.