Search Suggest

Scrivere Query performanti ...la tua Query è SARGABLE?

Cari lettori, oggi si cambia argomento!

Siete stati bravi: avete resistito a ben tre miei articoli sul database TEMPDB di SQL Server e quindi oggi parliamo d'altro..

Volevo infatti iniziare a parlare di come scrivere Query che siano performanti.
Premetto che sarà, per forza di cose, una introduzione nella quale volutamente non scenderò in dettagli. L'obbiettivo per oggi è infatti focalizzare l'attenzione, più che altro, sui concetti principali.

Ma come al solito, se avete domande, scrivetemi! 

Iniziamo!

Diciamo subito che una Query è performante quando sfrutta la presenza degli indici presenti sulle tabelle; solo in questo modo infatti i dati verranno estratti "velocemente".

Ovviamente possiamo creare anche tabelle prive di indici (che sono dette tabelle HEAP), in questo caso però l'unico modo per recuperare i dati sarà quello di leggere completamente la tabella.

Vediamolo chiaramente con un semplice esempio:

Per prima cosa creiamo una tabella PERSON con queste tre colonne: ID, FIRSTNAME e LASTNAME, poi eseguiamo questa semplice Query:


       
SELECT FIRSTNAME FROM PERSON WHERE FIRSTNAME = 'LUCA'

Se guardiamo il piano di esecuzione, vediamo subito che viene eseguita la scansione dell'intera tabella.

 
Bene, ora facciamo un passo avanti!

Aggiungiamo un indice sulla colonna FIRSTNAME tramite questa instruzione T-SQL:

       
CREATE INDEX IDX_PERSON_FIRSTNAME ON PERSON (FIRSTNAME)


Se adesso rifacciamo la stessa Query possiamo vedere come cambia il piano di esecuzione.
Innanzitutto vien utilizzato l'indice appena creato:
 
Qual'è l'effetto più evidente? L'effetto più evidente è che vengono lette solamente le righe interessate!

Possiamo stimare il guadagno di performance, semplificando molto, considerando il tempo di esecuzione della Query come direttamente proporzionale al numero di righe lette: 18 contro circa 600.000

Il primo concetto è quindi: Cerchiamo di evitare che la Query che stiamo sviluppando faccia la scansione di una tabella o anche solo una scansione di un indice. 

Ma c'è un però! Siamo veramente sicuri che la query che stiamo scrivendo utilizzi effettivamente un indice presente? La risposta è "non è detto".

Vediamone il perchè parlando del concetto importante di SARGABLE 

SARGABLE è un acronimo dato dalle tre parole: Search ARGument ABLE 

Si dice che una Query è SARGABLE se il motore del DBMS può trarre vantaggio da un indice (ovvero usarlo in SEEK) per velocizzare l'esecuzione della Query. 

Vediamo... la semplice Query di prima è SARGABLE? Si perchè effettivamente fa la SEEK dell'indice che avevo appena creato.


Proviamo adesso con un Query appena più complicata.

Cerchiamo tutte le persone in cui il primo carattere del nome è "C".

Eseguiamo ad esempio questa Query:
       
SELECT FIRSTNAME FROM PERSON WHERE LEFT(FIRSTNAME,1) = 'C'

Vediamo cosa succede guardando il piano di esecuzione.
L'indice viene si utilizzato ma attenzione.. ne viene fatta la scansione (SCAN) cioè viene letto interamente.

Dato che non viene fatta la SEEK quindi diciamo che la funzione LEFT non è SARGABLE:

Ma se la funzione LEFT non è SARGABLE cosa possiamo fare? Bhe proviamo di cercarne una che invece lo sia.

Se scrivessimo la Query utilizzando l'operatore LIKE?

       
SELECT FIRSTNAME FROM PERSON WHERE FIRSTNAME LIKE 'C%'

WOW! Questa volta viene fatta la SEEK dell'indice e quindi l'operatore LIKE è SARGABLE:


Per oggi basta!

Se vi piace l'articolo e se lo ritenete utile seguitemi e possiamo continuare con l'argomento, magari guardando per bene quali funzioni sono SARGABLE e quali no.


Luca Biondi @ SQLServerPerformance blog!









Post a Comment