Ottimizzazione di una Query Annidata NOT IN

Sebbene risultino di migliore comprensione e leggibilità, le query annidate rischiano spesso di generare problemi prestazionali che possono portare in timeout la connessione verso il DB e lasciare appeso un processo sul DBMS. Nel seguito sarà presentata una soluzione di riscrittura di una query annidata di tipo NOT IN attraverso sostituzione con una LEFT JOIN.

Per semplicità consideriamo due tabelle A e B tra le quali esiste una relazione di tipo FOREIGN KEY ovvero B ha una chiave esterna verso A denominata IDA.

A ( ID, … )
B ( ID, IDA, … )

Supponendo di dover recuperare da A tutte le tuple non referenziate da B, la seguente query annidata risolve il problema in modo elegante:

SELECT *
FROM A
WHERE ID NOT IN (
SELECT IDA
FROM B
)

Il piano di esecuzione di una query di questo tipo prevede innanzitutto il recupero dalla tabella B di tutti i valori della chiave esterna IDA, con conseguente conservazione in memoria dei risultati, quindi il confronto di tali valori con gli ID di A. Tale comportamento, soprattutto nel caso di tabelle di elevata dimensione,  comporta una enorme consumo di risorse sia di memoria che di cpu.

Una intelligente riscrittura della query comporta l’utilizzo di una LEFT JOIN con un notevole incremento delle prestazioni. La query riscritta è la seguente:

SELECT A.*
FROM A LEFT JOIN B ON A.ID=B.IDA
WHERE B.ID IS NULL

Il trucco consiste nel fatto che la LEFT JOIN recupera tutte le tuple di A e, se presenti, quelle di B che soddisfano la condizione di join. Attraverso la clausola WHERE vengono poi escluse tutte le tuple di A che hanno una corrispondente tupla in B, ovvero si ottengono tutte le righe che non sono referenziate da B.

CONCLUSIONE

In generale non vi è alcuna differenza nelle prestazioni tra un’istruzione che include una subquery e una versione equivalente dal punto di vista semantico ma priva di subquery. Però, in alcuni casi in cui è necessario verificare l’esistenza di dati specifici, l’utilizzo di un join consente di ottenere prestazioni migliori.

How useful was this post?

Click on a star to rate it!

Average rating 5 / 5. Vote count: 1

No votes so far! Be the first to rate this post.

As you found this post useful...

Follow us on social media!