Consulta que coincide con varias condiciones potenciales: ¿Diseño adecuado?

Estoy trabajando en una consulta para encontrar registros en una tabla de entradas nuevas que coincidan con registros en una tabla de entradas históricas, donde la coincidencia podría estar en uno de muchos campos. En otras palabras:

"Mostrar todos los registros donde current.id = archive.id o current.name = archive.name o current.address = archive.address"

Mi SQL para esta consulta es el siguiente:

SELECT current.id, current.name, current.address FROM current
INNER JOIN archive
ON
    current.id = archive.id OR
    current.name = archive.name OR
    current.address = archive.address

Cuando lo ejecuto, toma SIEMPRE, y esto es en la primera carga de datos; El archivo siempre tendrá alrededor de 300,000 registros, pero el actual fluctuará entre 500 y 40,000.

¿Hay una mejor manera de escribir esta consulta? O, ¿mi consulta es sólida, pero mi base de datos subyacente podría tener problemas?

preguntado el 03 de mayo de 12 a las 21:05

1 Respuestas

Crear un índice en los 3 campos en cuestión en cada tabla probablemente ayudaría (especialmente en la tabla de archivo si es muy grande), pero intente esto en su lugar:

SELECT current.id, current.name, current.address
FROM current
INNER JOIN archive
ON
    current.id = archive.id

UNION

SELECT current.id, current.name, current.address
FROM current
INNER JOIN archive
ON
    current.name = archive.name

UNION 

SELECT current.id, current.name, current.address
FROM current
INNER JOIN archive
ON
    current.address = archive.address

Esta consulta le permitiría indexar los campos individualmente (lo que aún debe hacer), lo que resulta en índices potencialmente más pequeños y un mejor rendimiento general.

El uso de OR en los criterios de unión realmente puede estropear el optimizador de consultas, lo que podría hacer que haga cosas subóptimas. los UNIONLos s son costosos, pero es más probable que su tiempo de consulta se dedique a la unión, y simplificar eso puede ayudar mucho.

contestado el 03 de mayo de 12 a las 21:05

También puede usar UNION ALL para que SQL Server no tenga que filtrar los duplicados como parte del paso de unión. Siempre puede filtrar los duplicados después del hecho. - Aarón Bertrand

Pregunta: ¿Debería ayudar un "donde existe" en lugar de una unión interna? Como no se recupera ningún valor del archivo... ¿O el mismo plan de ejecución? - Rafael Althaus

@RaphaëlAlthaus, ¿te refieres a una serie de WHERE EXISTS unidos como mi respuesta, o una sola WHERE EXISTS con OR condiciones? Si es lo primero, debería funcionar igual que mi respuesta. Si es lo último, espero que sea lento según el OP. - chris shain

La solución "UNIÓN" funcionó; 26 minutos hasta 1 segundo. - Vengador IVR

Es sorprendente la gran diferencia que pueden hacer estas pequeñas cosas, ¿no es así? - chris shain

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.