我正在尝试确定我的数据库中不再使用哪些索引。我使用以下查询运气很好:
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次?
答案 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%'
您可以将此信息填充到临时表中,然后使用它来查询所使用的索引,查看索引使用情况统计信息。
很抱歉,我无法给你一个实际的例子,只是一个理论的例子......