USE [HCITools] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[mon_Collect_Stats_Index]') AND type in (N'P', N'PC')) DROP PROCEDURE [dbo].[mon_Collect_Stats_Index] GO USE [HCITools] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE PROCEDURE [dbo].[mon_Collect_Stats_Index] AS /*============================================================================= Explication du traitement realise par la SP ------------------------------------------- La SP va stocker l'ensemble des statistiques des index contenues dans la DMV sys.dm_db_index_usage_stats et créer un historique pour chaque redémarrage du serveur Contexte d'utilisation ---------------------- Appelé depuis le job D92020 - Collect Stats Index Creation : 03.08.15 / FLA Modifications : 18.11.2015 / FLA : Ajout d'un try/catch dans le cas où les bases sont indisponibles et éviter ainsi de ne pas récuperer les stats des bases suivantes 04.10.2017 / FLA : Ajout de la gestion des environnements 24.09.2018 / FLA : Remove references to undocumented system tables 17.03.2022 / FLA : Change DBA mail =============================================================================*/ set nocount on; /*------------------- Declaration des variables --------------------*/ declare @databaseID smallint, @databasename sysname, @restartdate datetime, @actualdate datetime, @sql nvarchar(4000), @messageError varchar (8000), @errno int, @errmsg varchar(255) /*------------ Affectation des parametres aux variables ------------*/ select @RestartDate = MIN(login_time) from sys.dm_exec_sessions select @actualdate = GETDATE() select @errno = 0 SET @messageError = '' SET @errmsg = '' IF EXISTS (SELECT type FROM master.cfg.InstanceContext WHERE type = 'PROD') BEGIN /*-------------------------- Traitement ---------------------------*/ BEGIN TRY DECLARE c_databases CURSOR FAST_FORWARD FOR select database_id, name from sys.databases where database_id > 4 open c_databases FETCH NEXT FROM c_databases into @databaseID, @databasename /* On parcourt chaque base de données pour récuperer les informations des index */ WHILE @@FETCH_STATUS = 0 BEGIN BEGIN TRY SET @sql = 'insert into dbo.Stats_index (SI_schemaname,SI_databasename,SI_tablename,SI_indexname,SI_indextype,SI_user_seeks,SI_user_scans,SI_user_lookups,SI_user_updates,SI_last_user_seek,SI_last_user_scan,SI_last_user_lookup,SI_last_user_update,SI_updatedate, SI_restartdate) select OBJECT_SCHEMA_NAME(so.object_id,'+ CAST(@databaseID AS nvarchar(4)) +'),'''+ @databasename +''',so.name,si.name,si.type_desc, null, null, null ,null ,null ,null, null ,null, CAST('''+ CONVERT(nvarchar(30),@actualdate,126) +''' as datetime), CAST('''+ CONVERT(nvarchar(30),@RestartDate,126) +''' as datetime) from '+ @databasename +'.sys.indexes si INNER JOIN '+ @databasename +'.sys.objects so ON so.object_id = si.object_id WHERE so.type COLLATE SQL_Latin1_General_CP1_CI_AS <> ''S'' /* NOT SYSTEM */ AND NOT EXISTS (select * from dbo.Stats_index as sti where ISNULL(sti.SI_indexname,'''') COLLATE SQL_Latin1_General_CP1_CI_AS = ISNULL(si.name,'''') COLLATE SQL_Latin1_General_CP1_CI_AS and sti.SI_tablename COLLATE SQL_Latin1_General_CP1_CI_AS = so.name COLLATE SQL_Latin1_General_CP1_CI_AS and sti.SI_databasename COLLATE SQL_Latin1_General_CP1_CI_AS = '''+ @databasename +''' COLLATE SQL_Latin1_General_CP1_CI_AS and sti.SI_schemaname COLLATE SQL_Latin1_General_CP1_CI_AS = OBJECT_SCHEMA_NAME(so.object_id,'+ CAST(@databaseID AS nvarchar(4)) +') COLLATE SQL_Latin1_General_CP1_CI_AS and SI_updatedate > CAST('''+ CONVERT(nvarchar(30),@RestartDate,126) +''' as datetime))' EXEC(@sql) /* On met à jour les stats des index dans la table dbo.Stats_index */ SET @sql = N'UPDATE dbo.Stats_index SET SI_user_seeks = ius.user_seeks, SI_user_scans = ius.user_scans, SI_user_lookups = ius.user_lookups, SI_user_updates = ius.user_updates, SI_last_user_seek = ius.last_user_seek, SI_last_user_scan = ius.last_user_scan, SI_last_user_lookup = ius.last_user_lookup, SI_last_user_update = ius.last_user_update, SI_updatedate = CAST('''+ CONVERT(nvarchar(30),@actualdate,126) +''' as datetime) FROM sys.dm_db_index_usage_stats ius INNER JOIN '+ @databasename + '.sys.indexes si ON si.object_id = ius.object_id AND si.index_id = ius.index_id AND ius.database_id = '+ CAST(@databaseID AS nvarchar(4)) +' WHERE SI_tablename COLLATE SQL_Latin1_General_CP1_CI_AS = OBJECT_NAME(ius.object_id,ius.database_id) COLLATE SQL_Latin1_General_CP1_CI_AS AND ISNULL(SI_indexname,'''') COLLATE SQL_Latin1_General_CP1_CI_AS = ISNULL(si.name,'''') COLLATE SQL_Latin1_General_CP1_CI_AS AND SI_databasename COLLATE SQL_Latin1_General_CP1_CI_AS = '''+ @databasename +''' COLLATE SQL_Latin1_General_CP1_CI_AS AND SI_schemaname COLLATE SQL_Latin1_General_CP1_CI_AS = OBJECT_SCHEMA_NAME(si.object_id,'+ CAST(@databaseID AS nvarchar(4)) +') COLLATE SQL_Latin1_General_CP1_CI_AS AND SI_updatedate > CAST('''+ CONVERT(nvarchar(30),@RestartDate,126) +''' as datetime)' EXEC(@sql) END TRY BEGIN CATCH select @messageError = @messageError + 'Collect_Stats_Index failed : ' + @databasename + ' ' + ERROR_MESSAGE() + CHAR(13) SET @errno = @errno + 1 END CATCH FETCH NEXT FROM c_databases into @databaseID, @databasename END CLOSE c_databases DEALLOCATE c_databases /* S'il y a une erreur, on envoie un mail aux DBA */ IF @messageError <> '' BEGIN exec aps_Send_Mail_with_template @in_param_varchar_2 = 'DBA_operator;', @in_job_type = 3, /* 3 = warning */ @in_param_varchar_3 = @messageError RAISERROR ('Erreur dans la SP [dbo].[mon_Collect_Stats_Index]',16,1) END /*---------------------- Traitement des erreurs ----------------------*/ END TRY BEGIN CATCH /* Traitement des erreurs (avec RaiseError) */ EXEC dbo.get_Error_Info @in_RaiseError = 1 END CATCH END GO