Sql-server – Index usage and update statistics do not correspond

index-tuningsql server

In order to discover unused and wrong indexes in sql server I went through the following article:
https://www.mssqltips.com/sqlservertutorial/256/discovering-unused-indexes/

It gives two queries that deliver index information:

SELECT OBJECT_NAME(A.[OBJECT_ID]) AS [OBJECT NAME], 
   I.[NAME] AS [INDEX NAME], 
   A.LEAF_INSERT_COUNT, 
   A.LEAF_UPDATE_COUNT, 
   A.LEAF_DELETE_COUNT 
FROM   SYS.DM_DB_INDEX_OPERATIONAL_STATS (db_id(),NULL,NULL,NULL ) A 
   INNER JOIN SYS.INDEXES AS I 
     ON I.[OBJECT_ID] = A.[OBJECT_ID] 
        AND I.INDEX_ID = A.INDEX_ID
WHERE  OBJECTPROPERTY(A.[OBJECT_ID],'IsUserTable') = 1

SELECT OBJECT_NAME(S.[OBJECT_ID]) AS [OBJECT NAME], 
   I.[NAME] AS [INDEX NAME], 
   USER_SEEKS, 
   USER_SCANS, 
   USER_LOOKUPS, 
   USER_UPDATES 
FROM   SYS.DM_DB_INDEX_USAGE_STATS AS S 
   INNER JOIN SYS.INDEXES AS I ON I.[OBJECT_ID] = S.[OBJECT_ID] 
AND I.INDEX_ID = S.INDEX_ID 
WHERE  OBJECTPROPERTY(S.[OBJECT_ID],'IsUserTable') = 1
   AND S.database_id = DB_ID()

Trying the queries my suspect was confirmed that several existing indexes are simply useless.

The article mentions that the results of query #1 shound correspond with results of query #2:

"The updates refers to how many times the index was updated due to data changes which should correspond to the first query above."

So LEAVE(insert/update/delete) Counts sould be = USER_Updates.

In my case they do not correspond at all. e.g:

  • A.LEAF_INSERT_COUNT=26219
  • A.LEAF_UPDATE_COUNT=0
  • A.LEAF_DELETE_COUNT=0

vs.

  • USER_UPDATES =1.550.063

    So my question is, what could possibly cause my data to dis-correspond that much?

Best Answer

About: sys.dm_db_index_operational_stats

The data returned by sys.dm_db_index_operational_stats exists only as long as the metadata cache object that represents the heap or index is available. This data is neither persistent nor transactionally consistent. This means you cannot use these counters to determine whether an index has been used or not, or when the index was last used. For information about this, see sys.dm_db_index_usage_stats (Transact-SQL).

The values for each column are set to zero whenever the metadata for the heap or index is brought into the metadata cache and statistics are accumulated until the cache object is removed from the metadata cache. Therefore, an active heap or index will likely always have its metadata in the cache, and the cumulative counts may reflect activity since the instance of SQL Server was last started. The metadata for a less active heap or index will move in and out of the cache as it is used. As a result, it may or may not have values available.

See: sys.dm_db_index_operational_stats (Transact-SQL)

On the other hand, sys.dm_db_index_usage_stats, which is mentioned above, is only reset when the service is restarted:

The counters are initialized to empty whenever the SQL Server (MSSQLSERVER) service is started.