Preambolo
Di recente, vedo troppi fanatici che commentano le domande di Oracle che dicono che “Non usare l’operatore (+), piuttosto usa la syntax JOIN”.
Domanda
Vedo che entrambi funzionano bene. Ma qual è la vera differenza tra usarli e cosa ti fa sentire usarli? Vorrei ricevere risposte, più dall’esperienza.
1. Is there anything to do with limitations in application, performance, etc. while using them? 2. What would you suggest for me?
Ho letto qualcosa sulla documentazione di Oracle, ma non abbastanza per farmi capire o sentirmi a mio agio con le informazioni complete.
Nota : sto pianificando la migrazione di oltre 200 pacchetti e procedure, se la parola chiave deve essere utilizzata al posto di (+)
3. Also is there any freeware tools to do the rewrite?
Pubblicare campioni
┌───────────────────────────────────┬─────────────────────────────────────────────┐ │ INNER JOIN - CONVENTIONAL │ INNER JOIN - ANSI SYNTAX │ ├───────────────────────────────────┼─────────────────────────────────────────────┤ │ SELECT │ SELECT │ │ emp.deptno │ ename, │ │ FROM │ dname, │ │ emp, │ emp.deptno, │ │ dept │ dept.deptno │ │ WHERE │ FROM │ │ emp.deptno = dept.deptno; │ scott.emp INNER JOIN scott.dept │ │ │ ON emp.deptno = dept.deptno; │ ├───────────────────────────────────┼─────────────────────────────────────────────┤ │ LEFT OUTER JOIN - CONVENTIONAL │ LEFT OUTER JOIN - ANSI SYNTAX │ ├───────────────────────────────────┼─────────────────────────────────────────────┤ │ SELECT │ SELECT │ │ emp.deptno │ ename, │ │ FROM │ dname, │ │ emp, │ emp.deptno, │ │ dept │ dept.deptno │ │ WHERE │ FROM │ │ emp.deptno = dept.deptno(+); │ scott.emp LEFT OUTER JOIN scott.dept │ │ │ ON emp.deptno = dept.deptno; │ ├───────────────────────────────────┼─────────────────────────────────────────────┤ │ RIGHT OUTER JOIN - CONVENTIONAL │ RIGHT OUTER JOIN - ANSI SYNTAX │ ├───────────────────────────────────┼─────────────────────────────────────────────┤ │ SELECT │ SELECT │ │ emp.deptno │ ename, │ │ FROM │ dname, │ │ emp, │ emp.deptno, │ │ dept │ dept.deptno │ │ WHERE │ FROM │ │ emp.deptno(+) = dept.deptno; │ scott.emp RIGHT OUTER JOIN scott.dept │ │ │ ON emp.deptno = dept.deptno; │ ├───────────────────────────────────┼─────────────────────────────────────────────┤ │ FULL OUTER JOIN - CONVENTIONAL │ FULL OUTER JOIN - ANSI SYNTAX │ ├───────────────────────────────────┼─────────────────────────────────────────────┤ │ SELECT │ SELECT │ │ * │ * │ │ FROM │ FROM │ │ emp, │ scott.emp FULL OUTER JOIN scott.dept │ │ dept │ ON emp.deptno = dept.deptno; │ │ WHERE │ │ │ emp.deptno = dept.deptno(+) │ │ │ UNION ALL │ │ │ SELECT │ │ │ * │ │ │ FROM │ │ │ emp, │ │ │ dept │ │ │ WHERE │ │ │ emp.deptno(+) = dept.deptno │ │ │ AND emp.deptno IS NULL; │ │ └───────────────────────────────────┴─────────────────────────────────────────────┘
PS : leggi il riepilogo delle risposte per tutti gli aggiornamenti raggruppati.
Se i tuoi oltre 200 pacchetti funzionano come previsto con la syntax “vecchio stile”, lascia che sia. SQL non inizierà a funzionare meglio dopo la migrazione alla syntax ANSI – è solo una syntax diversa.
Detto questo, la syntax ANSI è più pulita: non si arriverà a un join normale se si dimentica (+) in un join esterno a più colonne.
In passato c’erano alcuni bug con la syntax ANSI ma se si va con l’ultima versione 11.2 o 12.1 dovrebbe essere già risolta.
Naturalmente, conoscete meglio il vostro ambiente e le vostre priorità – come ha detto SchmitzIT – La syntax ANSI fa parte dello standard SQL e sarebbe di aiuto quando si andrebbe ad utilizzare un altro prodotto RDBMS.
In 11g dovresti utilizzare la syntax di join ANSI. È più flessibile (supporto per join esterni completi e join partizionati), e come afferma la documentazione:
Oracle consiglia vivamente di utilizzare la syntax di join della clausola FROM più flessibile mostrata nell’esempio precedente.
Questa è una ragione sufficiente.
Raggruppando le risposte insieme
Possibile trappola nell’uso della syntax ANSI sul motore 12c
Inclusa una possibilità di bug in JOIN in 12c. Vedi qui
AZIONE SUPPLEMENTARE:
Quest SQL optimizer tool
riscrive la syntax SQL in ANSI.
Oltre ai motivi menzionati da altri, l’utilizzo degli operatori JOIN garantisce che il codice SQL sia conforms ANSI e consentirebbe quindi a un’applicazione front-end di essere più facilmente trasferita per altre piattaforms di database.
Separare la query in condizioni di join e in cui le condizioni possono fornire all’ottimizzatore un suggerimento aggiuntivo. Le condizioni di unione hanno una selettività molto bassa su ciascun tavolo e un’elevata selettività sulle tuple nel prodotto trasversale teorico. Le condizioni nell’istruzione where solitamente hanno una selettività molto più alta.
In una condizione di join per ogni riga a sinistra è molto probabile un valore a destra (e viceversa). Quindi tali condizioni sono buone per unire i risultati di due tabelle, ma non aiutano molto ad eliminare i valori di ogni singola tabella dal set di risultati.
Le condizioni nella clausola where in genere possono essere utilizzate per eliminare singole righe da una tabella dal set di risultati.
Quindi è una buona strategia per eseguire prima le condizioni sulle singole tabelle ed eliminare il maggior numero ansible di righe dal set di risultati. Successivamente, è ansible utilizzare le condizioni di unione per combinare le righe rimanenti.
Non è chiaro se l’ottimizzatore Oracle utilizzi realmente la posizione della condizione nell’istruzione SQL come suggerimento per l’ottimizzazione della query. Immagino che sia più interessato ai fatti concreti nelle statistiche della tabella (ci sono stati alcuni cambiamenti nel modo in cui Oracle gestisce i diversi join in 11g R1, vedi questo post dal team di Oracle Optimizer per maggiori dettagli).
Almeno per me, come umano, è molto utile sapere se una dichiarazione ha una selettività su un tavolo singe quando cerco di capire e ottimizzare una query. Dovresti considerare questo anche quando vuoi mettere più condizioni in una clausola ON (ad es. ON (ax=bx AND ay=by
) vs. ponendo una delle condizioni nel dove clasue: Basta controllare, quanto è selettiva la condizione.
Per le query esistenti mantenere la syntax così com’è. Quando crei una nuova query o rifattori uno esistente, prova a ordinare i predicati sulla selettività usando la syntax “JOIN ON”: Se non è selezionabile su una singola tabella, inseriscilo nella parte ON, altrimenti nella parte WHERE.
Il segno (+) utilizzato in outer join è la syntax Oracle per join esterni
Dalle informazioni raccolte da fonti oracle affidabili ho potuto vedere che è ansible mantenere la syntax Oracle outer join (+) per i pacchetti esistenti poiché ci sono più di 200 pacchetti e poiché internamente Oracle li converte ancora dalla syntax ANSI alla syntax Oracle.
Si prega di utilizzare la syntax ANSI in futuro dove ci sono limitazioni per l’utilizzo dell’operatore (+)
Si prega di trovare i collegamenti per una spiegazione dettagliata sul (+) segno Outer join che potrebbe aiutarti a decidere sulla tua migrazione
Oracle Outer Join syntax e syntax ANSI
Limitazioni dell’uso (+) Join esterni
Ulteriori informazioni su Oracle outer join
(+) Join esterno Operatore consigliato in Java quando si utilizzano i driver JDBC Oracle
Come pratica, dovresti sempre usare la syntax ANSI. Meglio non rielaborare su pacchetti e procedure. Piuttosto puoi correggere le cose quando fai qualsiasi manutenzione su quegli script individualmente. Non ci sarà alcuna differenza nei piani a causa della syntax.
Lo strumento di ottimizzazione SQL Quest riscrive con tutte le possibili combinazioni per trovare un piano migliore. Quindi è ancora necessario cercare uno SQL dai suoi 100+ risultati.
Ho usato entrambi gli approcci su diversi progetti e preferisco la syntax JOIN
.
ON
e nelle condizioni del filtro nella clausola WHERE
. Alcuni esperti hanno detto che la syntax (+) non consente i join esterni completi. Lo fa, quindi questo non è il problema: (LEFT OUTER JOIN) UNION ALL (RIGHT OUTER JOIN).
Altri hanno detto che le prestazioni sono la ragione per fare il passaggio. Questo è un mucchio di BS, specialmente in SQL. Certo, ci sono alcune linee guida, ma ogni query e ogni database ha le sue peculiarità, è necessario sintonizzarsi su specifiche non per situazioni generali.
I motivi per passare da (+), oltre a non essere standard, sono i suoi limiti rispetto alla nuova syntax esplicita: http://docs.oracle.com/cd/E16655_01/server.121/e17209/queries006.htm#SQLRF52354 . Iniziare a leggere da qui: “Oracle consiglia di utilizzare la syntax OUTER JOIN della clausola FROM anziché l’operatore Oracle join”.
Parlando dall’esperienza lavorativa, l’uso del JOIN
piuttosto che (+)
è più semplice, più veloce, più bello e meglio lavorare con la soluzione, specialmente quando si lavora con selezioni multi database (attraverso sinonimi), con un sacco di tabelle ( es .: 40+ tavoli) in un grande database (più di 1000 tavoli, alcune tabelle con più di 2 miliardi di file), sentirai una grande differenza.