Después de de nuestra extensa selección de información dimos con la respuesta este conflicto que tienen ciertos los lectores. Te regalamos la respuesta y esperamos serte de mucha ayuda.
Solución:
Pero en el ejemplo, la primera consulta tiene una condición en la columna a
mientras que la segunda consulta tiene una condición en la columna b
. Esto probablemente vino de una consulta que es difícil de optimizar:
SELECT * FROM mytable WHERE a=X OR b=Y
Esta consulta es difícil de optimizar con una indexación de árbol B simple. ¿El motor busca un índice en la columna? a
? o en la columna b
? De cualquier manera, buscar el otro término requiere un escaneo de tabla.
De ahí el truco de usar UNION para separar en dos consultas para un término cada una. Cada subconsulta puede utilizar el mejor índice para cada término de búsqueda. Luego combine los resultados usando UNION.
Pero los dos subconjuntos pueden superponerse, porque algunas filas donde b=Y
también puede tener a=X
en cuyo caso tales filas ocurren en ambos subconjuntos. Por lo tanto, debe realizar una eliminación por duplicado o, de lo contrario, ver algunas filas dos veces en el resultado final.
SELECT * FROM mytable WHERE a=X
UNION DISTINCT
SELECT * FROM mytable WHERE b=Y
UNION DISTINCT
es costoso porque las implementaciones típicas ordenan las filas para encontrar duplicados. Al igual que si usas SELECT DISTINCT ...
.
También tenemos la percepción de que es aún más trabajo “desperdiciado” si los dos subconjuntos de filas que está uniendo tienen muchas filas en ambos subconjuntos. Son muchas filas para eliminar.
Pero no hay necesidad de eliminar los duplicados si puede garantizar que los dos conjuntos de filas ya son distintos. Es decir, si garantiza que no hay superposición. Si puede confiar en eso, entonces siempre sería imposible eliminar los duplicados y, por lo tanto, la consulta puede omitir ese paso y, por lo tanto, omitir la clasificación costosa.
Si cambia las consultas para garantizar que seleccionen subconjuntos de filas que no se superponen, eso es una victoria.
SELECT * FROM mytable WHERE a=X
UNION ALL
SELECT * FROM mytable WHERE b=Y AND a!=X
Estos dos conjuntos están garantizados para no tener superposición. Si el primer conjunto tiene filas donde a=X
y el segundo conjunto tiene filas donde a!=X
entonces no puede haber ninguna fila que esté en ambos conjuntos.
Por lo tanto, la segunda consulta solo detecta alguno de las filas donde b=Y
pero cualquier fila donde a=X AND b=Y
ya está incluido en el primer set.
Entonces la consulta logra una búsqueda optimizada para dos OR
términos, sin producir duplicados y sin requerir UNION DISTINCT
operación.
Reseñas y puntuaciones del post
No se te olvide dar recomendación a este tutorial si te fue de ayuda.