Di sottoquery ed ottimizzazioni (parte 1)

Buongiorno a tutti, ben ritrovati.

Grazie per le tante visite (ben 1200 in circa un mese e mezzo sono tante per un technical-blog appena nato), mi raccomando continuate così!
Grazie ancor di più per gli apprezzamenti che fanno sempre molto piacere.

Ho cercato di rendere il blog più leggibile, ho aggiunto i post più popolari e infine ho inserito anche la possibilità di ricevere una notifica via mail alla pubblicazione un nuovo articolo.
Se la trovate una buona idea allora iscrivetevi e riceverete i nuovi articoli appena sfornati ...ancora caldi!

Lasciate le ferie alle spalle partiamo oggi parlando di "uno degli argomenti core" di questo blog ovvero la scrittura ottimale e performante delle Query.
Lo vorrei fare assieme a voi analizzando come vengono gestite in SQL Server le sottoquery (subquery in inglese).

 

Le SottoQuery


Partiamo da un esempio.
Tante volte osserviamo delle interrogazioni che hanno al loro interno altre Query. Può avvenire sia nella select che nella where.

Quante volte avete trovato delle stringhe SQL scritte più o meno così?


SELECT
  Tes.ID, Tes.DataOrdine,
  (SELECT MAX(Det.Prezzo) FROM Dettaglio AS Det WHERE Tes.Id = Det.Idtestata) AS MaxPrezzo,
  (SELECT MAX(Det.Prezzo2) FROM Dettaglio AS Det WHERE Tes.Id = Det.Idtestata) AS MaxPrezzo2,
  (SELECT MAX(Det.Prezzo3) FROM Dettaglio AS Det WHERE Tes.Id = Det.Idtestata) AS MaxPrezzo3,
  (SELECT MAX(Det.Prezzo4) FROM Dettaglio AS Det WHERE Tes.Id = Det.Idtestata) AS MaxPrezzo4
FROM Testata AS Tes
     


A fronte di una SELECT sulla tabella Master che nel nostro esempio si chiama Testata sono presenti più (4) sotto select che estraggono dati da una tabella di dettaglio.

Tutto funziona bene finchè i dati contenuti nelle tabelle sono pochi.
Poi, piano piano i dati aumentano ed il tempo di esecuzione inizia ad aumentare.
Il vostro cliente inzia a lamentarsi delle scarse prestazioni.

Come mai?  

Per capirlo meglio osserviamo innanzitutto come l'optimizer di SQL Server risolve la query. 

Il piano di esecuzione è questo:

 

Notiamo che, per prima cosa, che tutte le 4 sottoquery estraggono dati contenuti nella tabella dettaglio.

E qui troviamo il primo concetto da tenere a mente 

Secondo logica sarebbe sufficiente leggere la tabella Dettaglio una sola volta.
Ma il problema è che utilizzando le sottoselect possiamo estrarre un solo risultato alla volta.
Per questo motivo occorre fare 4 sottoselect.

P.S. Se è sufficiente una sola interrogazione sulla tabella Dettagli ma siamo costretti a farne 4 diciamo che la soluzione è sub-ottimale.

Secondo aspetto che stiamo osservando in questo momento:
L'optimizer di SQL Server non è in grado di ottimizzare casistiche di questo tipo.

Questi due aspetti ci portano a dire di evitare di usare quando possibile le sottoquery.

Ma come risolvere? Come migliorare facendo una sola interrogazione sulla tabella Dettaglio?

bhe se volete saperlo seguitemi nella seconda parte di questo post!.
 

Se non volete perdervelo vi suggerisco di iscrivervi. Riceverete una notifica via mail all'uscita di ogni nuovo articolo.


Ciao! A prestissimo!

Luca Biondi @ SQLServerPerformance blog!








Next post: Di sottoquery ed ottimizzazioni (parte 2)

Previous post: Le Common Table Expression (CTE) che cosa sono?

Comments

I Post più popolari

SQL Server, execution plan and the lazy spool (clearly explained)

SQL Server, datetime vs. datetime2

How to solve EXECUTE Permission denied on object 'sp_send_dbmail'