Hello colleagues,
do you know how to get list of unused indexes regardless of restarts of MS-SQL-Server or Database?
Because (if I understand correctly to information in BOL ) all content of dynamic management view sys.dm_db_index_usage_stats is deleted during restart of MS-SQL-Server or Detach Database.
Due to when I use my next script (to generate report with list of unused indexes) immediately (or after short time) after restart of MS-SQL-Server it contains misleading/confusing information.
:-(
USE [AdventureWorks] GO DECLARE @CurrDate as varchar(10), @CurrTime as varchar(5), @DatePartsSeparator as char(1), @EmptyDate as smalldatetime; SET @DatePartsSeparator = '/'; SET @CurrDate = RIGHT ('0' + CONVERT(varchar,DATEPART (day,GETDATE())), 2); SET @CurrDate = @CurrDate + @DatePartsSeparator; SET @CurrDate = @CurrDate + RIGHT ('0' + CONVERT(varchar,DATEPART (month,GETDATE())), 2); SET @CurrDate = @CurrDate + @DatePartsSeparator; SET @CurrDate = @CurrDate + CONVERT(varchar,DATEPART (year,GETDATE())); SET @CurrTime = RIGHT ('0' + CONVERT(varchar,DATEPART (hour,GETDATE())), 2); SET @CurrTime = @CurrTime + ':'; SET @CurrTime = @CurrTime + RIGHT ('0' + CONVERT(varchar,DATEPART (minute,GETDATE())), 2); SET @EmptyDate = CONVERT(smalldatetime, '01' + @DatePartsSeparator + '01' + @DatePartsSeparator + '2000'); SELECT SERVERPROPERTY('servername') AS [Server] , DB_NAME(s.database_id) AS [Database] , o.type_desc [ObjectType] , o.name AS [Object] , i.name AS [Index] , (user_seeks + user_scans + user_lookups) AS Reads , user_updates AS Writes , ((SELECT SUM(p.rows) FROM sys.partitions p WHERE p.index_id = s.index_id AND s.object_id = p.object_id) / 100) AS [Rows(1000)] , CASE WHEN s.user_updates < 1 THEN 100 ELSE CAST(1.00 * (s.user_seeks + s.user_scans + s.user_lookups) / s.user_updates AS decimal (12,5)) END AS Reads_per_Write , (SELECT TOP 1 luu.[Last_User_Usage] FROM ( SELECT COALESCE(s.last_user_lookup, @EmptyDate) AS [Last_User_Usage] UNION SELECT COALESCE(s.last_user_scan, @EmptyDate) AS [Last_User_Usage] UNION SELECT COALESCE(s.last_user_seek, @EmptyDate) AS [Last_User_Usage] ) AS luu ORDER BY luu.[Last_User_Usage] DESC) AS [Last_User_Usage] , COALESCE(s.last_user_update, @EmptyDate) AS [Last_User_Update] , CASE WHEN i.is_disabled = 0 THEN 'N' ELSE 'Y' END AS [Disabled] , i.index_id , o.create_date AS [Index_Created] , o.modify_date AS [Index_Modified] , u.name AS [Index_Owner] , @CurrDate AS [This_Report_Created] , @CurrTime AS [This_Report_Created_Time] , CONVERT(CHAR(40), SUSER_SNAME()) AS [This_Report_Created_by_User] , 'DROP INDEX ' + QUOTENAME(i.name) + ' ON ' + QUOTENAME(DB_NAME(s.database_id)) + '.' + QUOTENAME(c.name) + '.' + QUOTENAME(OBJECT_NAME(s.object_id)) as 'drop statement' FROM sys.dm_db_index_usage_stats s INNER JOIN sys.indexes i ON i.index_id = s.index_id AND s.object_id = i.object_id INNER JOIN sys.objects o ON s.object_id = o.object_id INNER JOIN sys.schemas c ON o.schema_id = c.schema_id LEFT OUTER JOIN sys.database_principals u ON OBJECTPROPERTY ( o.object_id , 'OwnerId' ) = u.principal_id WHERE OBJECTPROPERTY(s.object_id,'IsUserTable') = 1 AND s.database_id = DB_ID() AND i.type_desc = 'nonclustered' AND i.is_primary_key = 0 AND i.is_unique_constraint = 0 AND o.type IN ('U','V') AND o.is_ms_shipped = 0 AND (SELECT SUM(p.rows) FROM sys.partitions p WHERE p.index_id = s.index_id AND s.object_id = p.object_id) > 10000 ORDER BY Reads; GO
__________________________________________________________ If isn't above described anything, the following applies: Technical details: * OS: Windows Server v2008-R2, English, Enterprise Edition, x64, SP1 ** My User-Account is member of 'Administrators' local security group. * MS-SQL-Server: v2008-R2, English, Enterprise Edition, x64, SP1 ** My User-Account is member of 'SysAdmin' db-role.