如何查找存储过程正在使用哪些索引?

时间:2010-02-11 21:07:08

标签: sql-server sql-server-2005 tsql

我正在尝试确定我的数据库中不再使用哪些索引。我使用以下查询运气很好:

SELECT   OBJECT_NAME(S.[OBJECT_ID]) AS [OBJECT NAME],
         I.[NAME] AS [INDEX NAME],
         i.Type_Desc as [Index Type],
         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 i.name is not null
AND 
    (   OBJECT_NAME(S.[OBJECT_ID]) = 'Table1'
        OR
        OBJECT_NAME(S.[OBJECT_ID]) = 'Table2'
        OR
        OBJECT_NAME(S.[OBJECT_ID]) = 'Table3'
    )
ORder by S.[OBJECT_ID], user_Seeks desc , user_scans desc

我现在想要找到的是存储过程导致上述查询报告的搜索,扫描和查找。此信息是否存储在系统视图/表中?

澄清

正如gbn指出存储过程不直接使用索引,它使用一个使用索引的表。以下是我希望澄清我在这里要问的内容的解释。

我是否可以确定导致上述索引使用的SQL运行?例如,如果报告的其中一个索引有10个User_Seeks,则可以确定exec sp_1导致该用法7次而exec sp_2导致该用法3次?

5 个答案:

答案 0 :(得分:2)

编辑(再次,问题更新后):

没有现实的机会。您可以尝试使用分析器并捕获文本计划。我曾经看过这个,它杀死了一台服务器:它记录了很多文字。 YMMV: - )

存储过程不使用索引。

存储过程使用然后使用索引的表(和索引视图)(或者不按照上面的方法使用)

无论是存储过程,视图,用户定义函数还是单独执行,SELECT col1, col2 FROM myTable WHERE col2 = 'foo' ORDER BY col1都是一样的。

编辑:我们的索引使用脚本,从某个地方下载......

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

答案 1 :(得分:2)

您拥有sys.dm_exec_query_stats中所有语句的执行次数,您可以使用sys.dm_exec_query_plan提取计划XML。该计划包含扫描操作员使用的详细信息,因此在这两者之间您可以根据您的要求编制大量信息。例如,以下查询将显示来自缓存计划的频繁运行语句中的IndexScan运算符,这些语句会导致许多逻辑读取:

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;

答案 2 :(得分:1)

给定索引名称,这将返回每个proc的定义(在“whole_query”中)和该proc中使用索引的实际SQL语句(在“query”中)。注意它运行得非常慢!

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

答案 3 :(得分:0)

在SQL管理工作室中,您可以使用“查询”菜单下的“显示执行计划”选项准确查看查询的执行方式。

答案 4 :(得分:0)

我无法在家访问SQL Management Studio,但也许您可以查看存储过程依赖项(即this存储过程依赖于这些表,因此可能会使用这些索引)

This page可能会给你一些线索,比如使用INFORMATION_SCHEMA.ROUTINES系统表:

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

您可以将此信息填充到临时表中,然后使用它来查询所使用的索引,查看索引使用情况统计信息。

很抱歉,我无法给你一个实际的例子,只是一个理论的例子......