Articoli di programmazione

SQLServer ed una semplice query per generare eventuali Indici mancanti nel nostro database

Per incrementare le prestazioni in lettura spesso un Indice si mostra risolutivo. SQLServer ci aiuta ad individuare quali Indici risultano mancanti

SQL.png
Gli #Indici sono essenziali per il buon funzionamento di un #database in fase di lettura. Il costo computazionale speso in fase di scrittura, per aggiornare l'indice, è spesso ripagato abbondantemente in fase di lettura quando i dati vengono reperiti senza eseguire lente scansioni di tabelle.

Un buon programmatore #SQL riesce ad individuare quasi per per istinto quali campi hanno bisogno di un indice, mentre disegna un database. Questo senza dubbio vale per situazioni semplici, ma spesso le cose si fanno complesse e bisogna allora reperire dati per elaborare una strategia di indicizzazione vincente.

#SqlServer ci aiuta con la seguente query che si appoggia ad una #DMV (Dynamic Management View).

Le DMW restituiscono informazioni sullo stato del server che possono essere utilizzate per monitorare l'integrità di un'istanza del server, diagnosticare i problemi e ottimizzare le prestazioni.


Le #DMW sono viste dinamiche create automaticamente dall'istanza SQLServer e restituiscono dati molto importanti circa lo stato dell'istanza stessa o di un database preciso. Raccolgono un insieme molto grande di informazioni, per esempio quando una determinata Store Procedure ha girato l'ultima volta, quanto tempo ha impiegato, quali risorse ha richiesto etc.

Eseguiamo la query sul nostro DB e vediamo direttamente la lista di Indici che, a quanto risulta dalle DMW, mancano nel nostro database. La Query fornisce l'impatto stimato medio ed il comando testuale per creare direttamente l'indice. Ovviamente prima di creare l'indice suggerito è bene eseguire un'analisi dell'indice stesso, soprattutto per vedere come questo impatta sulle scritture.


SELECT TOP 25
dm_mid.database_id AS DatabaseID,
dm_migs.avg_user_impact*(dm_migs.user_seeks+dm_migs.user_scans) Avg_Estimated_Impact,
dm_migs.last_user_seek AS Last_User_Seek,
OBJECT_NAME(dm_mid.OBJECT_ID,dm_mid.database_id) AS [TableName],
'USE ' + db_name(dm_mid.database_ID) + char(13) + char(10) +
'GO ' + char(13) + char(10) +
'CREATE INDEX [' + convert(nvarchar(50), NEWID()) + 'SUG_IX_' + OBJECT_NAME(dm_mid.OBJECT_ID,dm_mid.database_id) + '_'
+ REPLACE(REPLACE(REPLACE(ISNULL(dm_mid.equality_columns,''),', ','_'),'[',''),']','') +
CASE
WHEN dm_mid.equality_columns IS NOT NULL AND dm_mid.inequality_columns IS NOT NULL THEN '_'
ELSE ''
END
+ REPLACE(REPLACE(REPLACE(ISNULL(dm_mid.inequality_columns,''),', ','_'),'[',''),']','')
+ ']'
+ ' ON ' + dm_mid.statement
+ ' (' + ISNULL (dm_mid.equality_columns,'')
+ CASE WHEN dm_mid.equality_columns IS NOT NULL AND dm_mid.inequality_columns IS NOT NULL THEN ',' ELSE
'' END
+ ISNULL (dm_mid.inequality_columns, '')
+ ')'
+ ISNULL (' INCLUDE (' + dm_mid.included_columns + ')', '')
+ char(13) + char(10) +
'GO '
AS Create_Statement
FROM sys.dm_db_missing_index_groups dm_mig
INNER JOIN sys.dm_db_missing_index_group_stats dm_migs
ON dm_migs.group_handle = dm_mig.index_group_handle
INNER JOIN sys.dm_db_missing_index_details dm_mid
ON dm_mig.index_handle = dm_mid.index_handle
--WHERE dm_mid.database_ID = DB_ID()
ORDER BY Avg_Estimated_Impact DESC
GO


#TSQL