I am trying to determine what indexes are no longer used in my Database. I have had great luck using the following query:
SELECT OBJECT_NAME(S.[OBJECT_ID]) AS
You have the number of executions for all statements in sys.dm_exec_query_stats, and you can extract the plan XML using sys.dm_exec_query_plan. The plan contains details like scan operators used, so between these two you can make up a lot of information from what you ask. For example the following query will show you the IndexScan operators in the frequently run statements from the cached plans that are causing many logical reads:
with xmlnamespaces ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' as sp)
select top(100)
q.total_logical_reads, q.execution_count
, x.value(N'@Database', N'sysname') as [Database]
, x.value(N'@Schema', N'sysname') as [Schema]
, x.value(N'@Table', N'sysname') as [Table]
, x.value(N'@Index', N'sysname') as [Index]
, substring(t.text, q.statement_start_offset/2,
case when 0 < q.statement_end_offset then (q.statement_end_offset - q.statement_start_offset)/2
else len(t.text) - q.statement_start_offset/2 end) as [Statement]
from sys.dm_exec_query_stats q
cross apply sys.dm_exec_query_plan(plan_handle)
cross apply sys.dm_exec_sql_text(sql_handle) as t
cross apply query_plan.nodes(N'//sp:IndexScan/sp:Object') s(x)
where execution_count > 100
order by total_logical_reads desc;