UNION
e UNION ALL
le query possono superare le query equivalenti utilizzando OR
- predicati connessi in determinate circostanze. A mia conoscenza, questo è parzialmente dovuto al fatto che i sottolettori UNION
possono essere eseguiti in parallelo e possono quindi avere il proprio "piano secondario" specifico per ciascuna parte del predicato connesso OR
, che è probabilmente molto più ottimale a causa di trasformazioni di query applicabili più semplici .Consentire a Oracle di trasformare i predicati collegati all'OR in operazioni UNION ALL
Tuttavia, la scrittura di predicati collegati è in genere molto più leggibile e concisa, anche se il factoring delle subquery è stato applicato a una soluzione UNION ALL
. La mia domanda è: c'è un modo per indicare a Oracle, che un singolo, costoso predicato connesso OR
deve essere trasformato in un'operazione UNION ALL
? Se esiste un tale suggerimento/metodo, in quali circostanze può essere applicato (ad esempio, devono essere presenti eventuali vincoli sulle colonne coinvolte nei predicati, ecc.)? Un esempio:
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, sono a conoscenza del /*+ USE_CONCAT */
suggerimento:
SELECT /*+ USE_CONCAT */ * FROM a
WHERE x = 1 OR y = 1
Ma non sembra produrre quello che mi serve (non forzata UNION ALL
operazione nel piano di esecuzione):
-------------------------------------------
| Id | Operation | Name | E-Rows |
-------------------------------------------
| 0 | SELECT STATEMENT | | |
|* 1 | TABLE ACCESS FULL| A | 2 |
-------------------------------------------
Forse, c'è qualche restrizione a questo suggerimento? Ho Oracle 11g2 disponibile per questo.
Quante righe (in% di tutte le righe) restituiranno la condizione 'x = 1 o y = 1' (nella tabella reale)? Che ne pensi di usare l'hint 'PARALLEL' nella query" o "? –
@a_horse_with_no_name: In realtà, la condizione (reale) è della forma '(flag_function() = 1 e condition1) o (flag_function() = 0 e condition2)'. Le due sotto-condizioni si escludono a vicenda a seconda di un 'flag_function() 'di PL/SQL. Ho notato che Oracle crea un piano molto migliore per questo quando si usa 'UNION ALL' piuttosto che quando si usa' OR'. 'PARALLEL' probabilmente non aiuterà molto, in quanto la quantità di dati non è così grande in questo caso, ma il piano è complesso ... Inoltre, questa query viene eseguita molto frequentemente nelle sessioni utente.Non vorrei ingannare troppe risorse con i suggerimenti 'PARALLEL' –
Queste query non sono equivalenti. È necessario utilizzare UNION anziché UNION ALL. Otterrai risultati diversi quando avrai righe in cui x e y uguali 1. – GriffeyDog