Query SARGABLE parte 2. Esempi

Ciao Ragazzi,


Oggi torniamo sulle Query SARGABLE.
Facciamo alcuni esempi di Query che sono SARGABLE e di Query che non lo sono!

Se vi siete persi la prima "puntata" è ancora non sapete l'importanza delle Query SARGABLE leggete prima il mio precedente articolo:  Scrivere Query performanti ...la tua Query è SARGABLE?

 

Siete pronti!  Via!


Creiamoci una semplice tabella di prova e riempiamola con un po di dati:


CREATE TABLE ELENCO
(ID INT IDENTITY(1,1),
 CODICE VARCHAR(3)
CONSTRAINT PK_Elenco_ID PRIMARY KEY CLUSTERED (id)) 

Il campo ID è autoincrementante ed è l'indice clustered.


Come primo esempio, scriviamo una delle Query più semplici

SELECT ID FROM ELENCO WHERE ID = 5


Vediamo il piano di esecuzione:



Come ci aspetteremmo per estrarre il dato voluto viene utilizzato l'indice clustered e viene effettuata una operazione di SEEK.

Ora cambiamo leggermente la Query:


SELECT ID FROM ELENCO WHERE ID + 1 = 5


Guardiamo nuovamente il piano di esecuzione.

Chi vede la differenza?


 

 

 

 

 


Bhe la differenza è notevole, viene utilizzato l'indice clustered ma ne viene fatta la scansione (SCAN)

Nel primo caso la Query è SARGABLE, nel secondo non lo è!!

Quindi attenzione, sommare anche solo un numero fisso al mio campo (numerico) che voglio cercare rende la Query non più SARGABLE.

L'optimizer di SQL Server non è in grado di trasformare la nostra Query!


Secondo esempio:

Aggiungiamo alla nostra tabella una colonna di tipo datetime.
Popoliamola con un po di dati e mettimoci sopra un indice.


ALTER TABLE ELENCO ADD START_DATE datetime
UPDATE ELENCO set START_DATE = CAST(GETDATE() AS int) - ID / 30
CREATE INDEX IDX_ELENCO_START_DATE on ELENCO (START_DATE)

La tabella sarà così:



Poi scriviamo questa Query:

SELECT START_DATE FROM ELENCO WHERE YEAR(START_DATE) = 2019


Guardiamo il piano di esecuzione:



Viene fatta la scansione ... quindi la funzione YEAR non è SARGABLE.

Possiamo scrivere la SELECT in modo migliore? Bhe si!

Ad esempio:

SELECT START_DATE FROM ELENCO WHERE START_DATE >= '2019/01/01' AND START_DATE <= '2019/31/12'


Ed ecco qua il risultato:

SQL Server questa volta esegue la SEEK!


Cosa ci fa capire questo esempio? Due cose:

  • Cerchiamo di trovare il modo di rendere SARGABLE una Query che non lo e'
  • Le maggior parte delle funzioni non sono SARGABLE 


Come compito per casa provate voi con varie funzioni .... MONTH, DAY, LEFT, SUBSTRING ... etc etc... vedremo che sono tutte non sargable!


Terzo e ultimo caso

L'operatore LIKE. Come si comporterà?

Proviamo..


SELECT CODICE FROM ELENCO WHERE CODICE LIKE '1%'


Bene l'operatore LIKE è SARGABLE:

 


Ma se scriviamo questa Query?


SELECT CODICE FROM ELENCO WHERE CODICE LIKE '%1%'

Chi indovina? ...tre due uno ... nessuno risponde?

Allora vediamo!



Non è SARGABLE!

La risposta completa è quindi DIPENDE!


A presto!

Luca Biondi @ SQLServerPerformance blog!







Next post: "INSERT di SELECT TOP(1) * FROM" vs. "INSERT TOP(1) di SELECT * FROM" + QUIZ

Previous post: DELETE Vs. TRUNCATE (Nessun server è stato maltrattato durante la scrittura di questo articolo)

Comments

I Post più popolari

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

SQL Server, datetime vs. datetime2

La clausola NOLOCK. Approfondiamo e facciamo chiarezza!