Siamo giunti al terzo ed ultimo appuntamento con l'approfondimento su SQL Server Health Check. Dopo aver visto i controlli preliminari e a livello di istanza e come verificare le proprietà dei database ed i carichi sulla CPU, proseguiamo con i dettagli su memoria fisica ed indici.
Memoria del sistema operativo e di SQL Server
Recuperiamo adesso informazioni sulla memoria fisica a livello di sistema operativo:
Una volta verificata la memoria del S.O.m scendiamo più in profondita’ esaminando invece l’utilizzo della memoria interna di SQL Server, tramite la seguente query:
Ecco l’output:
Quanto sopra ci indica la memoria effettivamente utilizzata da SQL Server, soprattutto se ci sono pagine bloccate in memoria, ed anche se la memoria fisica o virtuale risulta insufficiente.
Altro parametro che assume particolare importanza, sempre riguardo la memoria, è il PLE (page life expenctancy), ricavabile dalla query sotto:
Il valore dell’output viene espresso in secondi e misura il tempo previsto di permanenza di una pagina di dati nella cache del buffer prima che venga scaricata o eliminata. Microsoft a suo tempo raccomandava un valore minimo di 300 secondi, sotto il quale si presumeva esserci pressione sulla memoria, ma con i moderni server i 300 secondi indicati non sono più consoni, quindi per il calcolo di un PLE efficiente si utilizza la formula:
PLE = (maxmemorySQLServer / 4) * 300
Di conseguenza se ad esempio la nostra istanza è configurata con un maxmemory uguale a 96Gb di RAM, il PLE sarà uguale a: (96/4)*300 = 7200 sec.
La cattura del PLE ad intervalli regolari, ci permetterà di individuare facilmente i momenti di maggiore pressione della memoria.
Passiamo, con le due query seguenti, ad analizzare le concessioni di memoria in sospeso:
Restituisce un valore che rappresenta il valore corrente delle concessioni di memoria in sospeso per l’istanza SQL Server. Il valore ottimale sarebbe zero: valori superiori indicano pressioni sulla memoria dovuta a query che utilizzano la memoria per ordinamento e l’hashing.
Anche in questo caso, valori sopra lo zero indicano una forte pressione sulla memoria; nello specifico, la query qui sopra indica il numero totale di processi in attesa di una concessione di memoria.
Se dalle query precedente si evidenziano valori anomali, con la query sotto si può indagare maggiormente sull’utilizzo complessivo della memoria in SQL Server:
Questa query permette di verificare cosa utilizza grandi quantità di memoria (oltre alla cache del buffer). Voce a cui prestare particolare attenzione è CACHESTORE_SQLCP, che si occupa della memoria per i piani di query ad hoc. Molta memoria utilizzate dal memory Clerk CACHESTORE_SQLCP, indica un utilizzo molto elevato di memoria per i piani ad uno singoli per query ad hoc.
Per visualizzare il testo e le dimensioni della query dei piani di query ad hoc monouso, utilizzare la seguente query:
Controlli a livello di database
Per andare verso il completamento del nostro sistema di Health Check puntiamo adesso ai singoli database, utilizzando delle query mirate sui database presenti nella nostra istanza.
Cominciamo con le due query seguenti, che forniscono informazioni sui percorsi fisici dei datafiles e t-log e sulle loro dimensioni;
La seconda query invece ci da informazioni più dettagliate sul t-log indicando lo spazio utilizzato, lo spazio totale e la percentuale di utilizzo. Il monitoraggio di queste informazione ci mette al riparo da eventuale riempimento del t-log.
La query seguente permette invece di raccogliere informazioni sull’I/O del database:
L’output mostrerà: il numero di letture e scritture per ciascun file del database, il numero dei byte letti e scritti, il numero di blocchi I/O di lettura e scrittura.
Anche il numero dei VLF (Virtual Log File) è un indicatore della salute di un database; sono informazioni che è possibile estrarre tramite la seguente query:
Un numero elevato di VLF può influire sulle prestazioni in scrittura nel T-log ed inoltre può avere effetto sui tempi di ripristino di un database. Il numero dei VLF può essere controllato allocando preventivamente lo spazio del t-log in maniera ottimale, dipendente dalla grandezza del database.
I VLF crescono ogni volta che il t-log si allarga; se la crescita è inferiore a 64 Mb, verranno aggiunti 4 VLF, se invece la crescita è tra i 64 Mb e 1 Gb, verranno aggiunti 8 VLF, mentre per crescite superiori a 1Gb, verranno aggiunti 16 VLF al T-log. Configurare il t-log in maniera ottimale per avere un numero di VLF non elevato dipende sostanzialmente dall’attività del database stesso e dal numero delle scritture che si prevedono.
Passiamo con la prossima query ad esaminare le attività delle query sui nostri database:
Restituisce le query memorizzate nella cache ordinate per numero di esecuzioni, con annesso lo statement.
La query seguente è similare alla precedente, ma prende in considerazione le SP in cache:
Controlli sugli indici
Informazioni che assumono particolare importanza sono quelle sugli indici; di seguito vedremo una serie di query che approfondiscono questo aspetto.
La prima query che vedremo riguarda gli indici non cluster che hanno più scritture che letture:
Lo scopo di questa query è rilevare gli indici non cluster cha hanno un alto numero di scritture e un numero molto basso di letture; si tratta di indici praticamente inutili, poiché si paga un costo per tenerlo attivo, ma non si ottiene nessun beneficio. Occorre sottolineare che le informazioni estratte dalla query vengono azzerate con il riavvio dell’istanza: tale informazione va tenuta presente per poter analizzare i dati in maniera più coerente. Attenzione anche ad alcuni indici che vengono utilizzati raramente perché indispensabili solo per alcune procedure.
La query seguente mostra invece gli indici mancanti in base al vantaggio offerto dall’indice:
La query mostra gli indici che SQL Server rileva come mancanti, in base al flusso di lavoro dei database ed in base al costo calcolato della query. Tuttavia prima di introdurre un indice, occorre verificare vari fattori: se la tabella è oggetto di molte scritture sarebbe meglio non aggiungere nuovi indici, poiché più indici rallenteranno le prestazioni di inserimento/aggiornamento/eliminazione sulla tabella. I campi last_user_seek e user_seek possono aiutare a scegliere se procedere con deploy dell’indice o meno; se il campo last_user_seek contiene un valore di pochi secondi o pochi minuti è probabile che effettivamente l’indice giovi al normale carico di lavoro. Se i valori sono più larghi, è probabile che l’indice non vada ad apportare alcun miglioramento. Il campo user_seek invece contiene un valore che identifica quante volte SQL Server ha stabilito che avrebbe avuto bisogno dell’indice.
La seguente query, mostra gli indici mancanti per i piani memorizzati nella cache del database corrente:
Questa query restituisce informazioni sui piani di esecuzione memorizzati nella cache che presentano avvisi di “missing index”. Restituisce il nome della SP, l’execution plan ed il conteggio degli utilizzi per quel piano di esecuzione.
La query sotto provvede a restituire informazioni sulle tabelle e sugli indici che utilizzano più spazio nel buffer pool di SQL Server:
Per avere informazioni sullo stato di compressione dei dati di tutte le tabelle è possibile utilizzare la query seguente:
La seguente query invece mostra l’ultima volta che le statistiche sono state aggiornate:
La query restituisce il nome e altre proprietà di ogni indice cluster, ordinati in base alla data dell’ultimo aggiornamento delle statistiche. Statistiche non aggiornate potrebbero portare SQL Server Query Optimizer a scegliere un piano di esecuzione con prestazioni più scarse rispetto ad un altro.
Particolare importanza assume anche la frammentazione degli indici, di conseguenza per scoprire quali indici hanno maggiore frammentazione, possiamo utilizzare la seguente query:
La query restituisce ogni tabella e indice del database, ordinato in base al grado di frammentazione medio e filtra gli indici che hanno meno di 500 pagine, poiché irrilevanti. Gli indici molto frammentati possono ridurre le prestazioni in termini di I/O e le prestazioni delle query, e possono contribuire anche ad aumentare lo spazio richiesto per il datafile.
Conclusioni
Un Health Check ha comunque bisogno di un sistema che si occupi delle catture a intervalli di tempo regolari correlato da un ulteriori sistema di reporting, che mostri i risultati del polling e che permetta di agevolare il DBA nella successiva elaborazione dei dati.
Per quanto riguarda le cattura si potrebbe ad esempio utilizzare un SSIS Package che vada in polling sulle istanze della farm, associato a Reporting Services oppure a Power BI. Ci sono altre modalità con cui poter effettuare il polling nelle istanze: ognuno può dare libero sfogo alla sua fantasia su come raggiungere l’obiettivo.
di Luciano Maugeri, pubblicato il 7 maggio 2026
Vuoi maggiori informazioni sul nostro Health Check per SQL Server ed Oracle?
Prenota un appuntamento con uno dei nostri esperti o contattaci direttamente.