Eliminar donde no está en consulta

Tengo una tabla de búsqueda ( ##lookup ). Sé que es un mal layout porque estoy duplicando datos, pero acelera enormemente mis consultas. Tengo una consulta que rellena esta tabla

 insert into ##lookup select distinct col1,col2,... from table1...join...etc... 

Me gustaría simular este comportamiento:

 delete from ##lookup insert into ##lookup select distinct col1,col2,... from table1...join...etc... 

Esto actualizaría claramente la tabla correctamente. Pero esto es una gran cantidad de inserción y eliminación. Se mete con mis índices y bloquea la tabla para seleccionar.

Esta tabla también podría actualizarse por algo como:

 delete from ##lookup where not in (select distinct col1,col2,... from table1...join...etc...) insert into ##lookup (select distinct col1,col2,... from table1...join...etc...) except if it is already in the table 

La segunda forma puede tomar más time, pero puedo decir "sin locking" y podré seleccionar de la tabla.

¿Alguna idea sobre cómo escribir la consulta de la segunda manera?

 DELETE LU FROM ##lookup LU LEFT OUTER JOIN Table1 T1 ON T1.my_pk = LU.my_pk WHERE T1.my_pk IS NULL INSERT INTO ##lookup (my_pk, col1, col2...) SELECT T1.my_pk, T1.col1, T1.col2... FROM Table1 T1 LEFT OUTER JOIN ##lookup LU ON LU.my_pk = T1.my_pk WHERE LU.my_pk IS NULL 

También puede usar WHERE NOT EXISTS en lugar de LEFT JOINs arriba para search la inexistencia de filas.

También es posible que desee examinar la instrucción MERGE si está en SQL 2008. De lo contrario, no mantendrá las tablas sincronizadas; solo mantendrá las PK sincronizadas. Si una de las columnas cambia en una tabla, pero no en la otra, no se reflejará anteriormente.

De cualquier manera, parece que debería considerar optimizar las consultas. Si bien la duplicación de los datos puede parecer una buena solución para sus problemas de performance, como puede ver, puede conllevar muchos dolores de cabeza (y esta es solo una). Es mejor que encuentres la causa subyacente del bajo performance y lo arregles en lugar de ponerte este feo fajín.

Todos los DELETE se registran, lo que mata el performance si su plan es destruir toda la tabla. Dependiendo de la cantidad de filas con las que esté tratando, puede estar bien simplemente usar el TRUNCATE no registrado.

¿Cuánto time toma su statement SELECT? Podría intentar algo como esto si la selección toma una pequeña cantidad de time y no la está ejecutando con frecuencia.

select distinct … INTO # tempTable1 de table1 … join … etc …

begin transaction drop table ## lookup select * into ## lookup from # tempTable1 commit transaction

La respuesta de Tom es probablemente la más sólida, pero pensé que me gustaría presentar algunas alternativas. ¿Sin embargo, no estoy seguro de por qué es necesaria una tabla temporal global en comparación con una tabla real?