SQL Server Ottimizzazioni: non omettere il nome dello schema! (schema name resolution)


Carissimi lettori!

Oggi, torniamo a parlare di ottimizzazione!
Già perché un sistema veloce è anche sinonimo di sistema di qualità!
Comprereste da Amazon se per aggiungere un articolo nel carrello impiegereste due o tre minuti? Non credo!

Si parte!

Con questo articolo vorrei sottolineare questo aspetto non tanto conosciuto: quando scriviamo le nostre Query (a proposito da pronunciarsi “Quiri”) è meglio specificare sempre lo Schema (pronunciato “Schima”)

In pratica:

SELECT * FROM DBO.TABELLA 

Anziché:
             
SELECT * FROM TABELLA 
 

Questo per due motivi:

Primo motivo


Se non specifichiamo lo schema sarà SQL Server a doverlo fare. 
Dovrà fare un paio di verifiche veloci che sono:
Determinare lo schema di default e verificare se esiste una tabella con quel nome nello schema di default
Se non esiste nessuna tabella allora dovrà anche verificare se una tabella con quel nome è presente nello schema dbo.

Normalmente sono operazioni svolte molto rapidamente e per questo motivo vengono gestite tramite gli spinlock.

Il problema però può insorgere quando il sistema è sotto carico ed in questo caso avremo che le prestazioni non scalano.

In questo caso potremmo individuare la problematica perché vedremo apparire problemi dei contenzione su tipo d’attesa SOS_CACHESTORE spinlock.

Quindi la soluzione migliore è quella di indicare lo schema!


Secondo motivo

E’ poi presente anche una ulteriore problematica.
Per capirla però occorrerà conoscere le basi del funzionamento del plan cache.

Ve lo racconto in una riga per cui perdonatemi l'estrema semplificazione: il plan cache non è altro un zona di memoria dove SQL Server memorizza le stringhe SQL già eseguite. Lo fa per una questione di prestazioni. Quando la nostra stringa SQL è già nel plan cache SQL Server non avrà più la necessità di "studiarsi" un piano di esecuzione ma utilizzerà quello contenuto nel plan cache.

Facciamo quindi una prova analizzando assieme il caso in cui eseguo una Query omettendo lo schema name.

Per osservare il cache plan attraverso questa query:
       
WITH QRY AS
( SELECT
   REFCOUNTS,USECOUNTS,SIZE_IN_BYTES, CACHEOBJTYPE,OBJTYPE,   ATTRIBUTE,VALUE,PLAN_HANDLE
FROM SYS.DM_EXEC_CACHED_PLANS ECP
  OUTER APPLY SYS.DM_EXEC_PLAN_ATTRIBUTES(ECP.PLAN_HANDLE) EPA
WHERE EPA.ATTRIBUTE='USER_ID'
)
SELECT
   REFCOUNTS,USECOUNTS,SIZE_IN_BYTES,CACHEOBJTYPE, OBJTYPE,ATTRIBUTE,VALUE, OBJECTID,[TEXT],[DBID]
FROM QRY
   CROSS APPLY SYS.DM_EXEC_SQL_TEXT(QRY.PLAN_HANDLE)
WHERE
DBID=DB_ID('MIO_DB') 

        
Eseguiamo quindi una semplice Query:

SELECT * FROM NOMETABELLA 

 
Ed eseguitamo eseguiamo la Query sopra.
Ed ecco il plan cache:
 


La riga evidenziata è quello relativa alla mia istruzione T-SQL.
Se osservate la colonna VALUE vedrete che vale 1.

Il valore 1 significa che la nostra SELECT sarà in cache solo per l'utente 1, che non è altro che il DBO.

Adesso scriviamo invece questa SELECT


SELECT * FROM DBO.NOMETABELLA 

E guardiamo nuovamente il plan cache:




Cosa notate?

La riga selezionata ha ora nel campo Value il valore -2.
Il valore -2 vuol dire che il plan cache è valido per tutti utenti.


Oggi quindi cosa abbiamo capito?

Abbiamo capito che è sempre meglio indicare in tutte le nostre Query lo schema!


Per oggi è tutto!
Vi aspetto al prossimo articolo!


Luca Biondi @ SQLServerPerformance blog!








Next post: https://sqlserverperformace.blogspot.com/2019/10/sql-server-transazioni-lock-e-deadlock.html

Previous post: SQL Server & Cambiare le impostazioni relative alla lingua

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!