How to find what Stored Procedures are using what indexes?

后端 未结 5 1133
终归单人心
终归单人心 2021-02-15 18:34

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         


        
相关标签:
5条回答
  • 2021-02-15 18:36

    In the SQL management studio, you can see exactly how the query is executed by using the "Display Execution Plan" option under the Query menu.

    0 讨论(0)
  • 2021-02-15 18:42

    Edit (again, after question update):

    No realistic chance. You could try profiler and capture the textplan. I saw this once and it killed a server though: it's a lot of text to record. YMMV :-)

    Stored procedures do not use indexes.

    Stored procs use tables (and indexed views) that then use indexes (or don't use as you've worked out above)

    Doing SELECT col1, col2 FROM myTable WHERE col2 = 'foo' ORDER BY col1 is the same whether it's in a stored procedure, view, user defined function or by itself.

    Edit: Our index usage script, downloaded from somewhere...

    SELECT
        o.name AS [object_name], 
        i.name AS index_name, 
        i.type_desc, 
        u.user_seeks, u.user_scans, 
        u.user_lookups, u.user_updates,
        o.type
    FROM
        sys.indexes i
        JOIN
        sys.objects o ON i.[object_id] = o.[object_id]
        LEFT JOIN 
        sys.dm_db_index_usage_stats u ON i.[object_id] = u.[object_id] AND 
                                        i.index_id = u.index_id AND 
                                        u.database_id = DB_ID()
    WHERE
        o.type IN ('U', 'V') AND
        i.name IS NOT NULL
    ORDER BY 
        u.user_seeks + u.user_scans + u.user_lookups, u.user_updates
    
    0 讨论(0)
  • 2021-02-15 18:51

    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;
    
    0 讨论(0)
  • 2021-02-15 18:54

    I don't have access to SQL Management Studio at home, but maybe you can look at the stored procdures dependancies (i.e. this store procedure depends on these tables and therefore may use these indexes)

    This page might give you some clue, like using the INFORMATION_SCHEMA.ROUTINES system table:

    SELECT routine_name, routine_type 
    FROM INFORMATION_SCHEMA.ROUTINES 
    WHERE ROUTINE_DEFINITION LIKE '%Employee%'
    

    You can populate this information into a temp table and then then use that to query for the indexes used, looking at the index usage stats.

    Sorry that I'm not able to give you a practical example, just a theorical example...

    0 讨论(0)
  • 2021-02-15 18:59

    Given an index name, this will return entire the definition of each proc (in "entire_query") and the actual SQL statement in that proc which uses the index (in "query"). Note it runs very slowly!

    declare @indexName nvarchar(255) = N'[IX_Transaction_TypeId_TranId_StatusId]'
    
    ;with xmlnamespaces ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' as sp)
    select 
        n.value(N'@Index', N'sysname') as IndexName,
        replace(t.text, '**', '') as entire_query,
        substring (t.text,(s.statement_start_offset/2) + 1, 
                ((case when s.statement_end_offset = -1 then len(convert(nvarchar(max), t.text)) * 2
            else
                s.statement_end_offset
            end 
            - s.statement_start_offset)/2) + 1) as query,
        p.query_plan
    from 
        sys.dm_exec_query_stats as s
        cross apply sys.dm_exec_sql_text(s.sql_handle) as t 
        cross apply sys.dm_exec_query_plan(s.plan_handle) as p 
        cross apply query_plan.nodes('//sp:Object') as p1(n)
    where
        n.value(N'@Index', N'sysname') = @indexName
    
    0 讨论(0)
提交回复
热议问题