UNION
y UNION ALL
las consultas pueden superar las consultas equivalentes utilizando OR
-predicados conectados en determinadas circunstancias. Que yo sepa, esto se debe en parte a que las subselecciones UNION
se pueden ejecutar en paralelo y pueden tener su propio "subplano" específico para cada parte del predicado OR
conectado, que probablemente sea mucho más óptimo debido a transformaciones de consulta aplicables más simples .Deje que Oracle convierta predicados conectados en OR en operaciones UNION ALL
Pero escribir OR
predicados comunicado con los suele ser mucho más legible y conciso, incluso si la factorización subconsulta se aplicaron a una solución UNION ALL
. Mi pregunta es: ¿hay alguna manera de indicarle a Oracle que un solo y costoso predicado OR
-connected debería transformarse en una operación UNION ALL
? Si existe tal sugerencia/método, ¿bajo qué circunstancias se puede aplicar (por ejemplo, si es necesario que existan restricciones en las columnas involucradas en los predicados, etc.)? Un ejemplo:
CREATE TABLE a AS
SELECT 1 x, 2 y FROM DUAL UNION ALL
SELECT 2 x, 1 y FROM DUAL;
-- This query...
SELECT * FROM a
WHERE x = 1 OR y = 1
-- Is sometimes outperformed by this one, for more complex table sources...
-- Note: in my case, I can safely apply UNION ALL. I know the two predicates to
-- be mutually exclusive.
SELECT * FROM a
WHERE x = 1
UNION ALL
SELECT * FROM a
WHERE y = 1
Nota, soy consciente de la /*+ USE_CONCAT */
pista:
SELECT /*+ USE_CONCAT */ * FROM a
WHERE x = 1 OR y = 1
Pero no parece producir lo que necesito (sin UNION ALL
funcionamiento forzado en el plan de ejecución):
-------------------------------------------
| Id | Operation | Name | E-Rows |
-------------------------------------------
| 0 | SELECT STATEMENT | | |
|* 1 | TABLE ACCESS FULL| A | 2 |
-------------------------------------------
Tal vez, hay alguna restricción a esta sugerencia? Tengo Oracle 11g2 disponible para esto.
¿Cuántas filas (en% de todas las filas) devolverá la condición 'x = 1 oy = 1' (en la tabla real)? ¿Qué pasa con el uso de la sugerencia 'PARALELO' en la consulta" o "? –
@a_horse_with_no_name: en realidad, la condición (real) es de la forma '(flag_function() = 1 y condition1) o (flag_function() = 0 y condition2)'. Las dos subcondiciones se excluyen mutuamente en función de un PL/SQL 'flag_function()'. Me he dado cuenta de que Oracle crea un plan mucho mejor para esto cuando se usa 'UNION ALL' en lugar de cuando se usa' OR'. 'PARALLEL' probablemente no ayude mucho, ya que la cantidad de datos no es tan grande en este caso, pero el plan es complejo ... Además, esta consulta se ejecuta con mucha frecuencia en las sesiones de los usuarios.No me gustaría ahogar demasiados recursos con las sugerencias 'PARALELAS' –
Esas consultas no son equivalentes. Debería usar UNION en lugar de UNION ALL. Obtendrá resultados diferentes cuando tenga filas donde tanto x como y sean 1. – GriffeyDog