Как узнать, какие хранимые процедуры используют какие индексы? - PullRequest
8 голосов
/ 12 февраля 2010

Я пытаюсь определить, какие индексы больше не используются в моей базе данных. Мне очень повезло, используя следующий запрос:

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 ]

2 голосов
/ 12 февраля 2010

У вас есть количество выполнений для всех операторов в sys.dm_exec_query_stats , и вы можете извлечь XML плана, используя sys.dm_exec_query_plan . План содержит такие детали, как используемые операторы сканирования, поэтому между ними вы можете получить много информации из того, что вы просите. Например, следующий запрос покажет вам операторы 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 голосов
/ 12 февраля 2010

Изменить (снова после обновления вопроса):

Нет реальных шансов. Вы можете попробовать профилировщик и захватить текстовый план. Я видел это однажды, и это убило сервер, хотя: много текста для записи. 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 голос
/ 17 июля 2013

Если задано имя индекса, будет возвращено полное определение каждого процесса (в «whole_query») и фактический оператор SQL в том процессе, который использует индекс (в «запросе»). Обратите внимание, что он работает очень медленно!

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 голосов
/ 12 февраля 2010

У меня нет доступа к SQL Management Studio дома, но, возможно, вы можете посмотреть на зависимости хранимых процедур (т.е. this процедура хранения зависит от этих таблиц и, следовательно, может использовать эти индексы)

Эта страница может дать вам некоторую подсказку, например, использовать системную таблицу INFORMATION_SCHEMA.ROUTINES:

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

Вы можете заполнить эту информацию во временной таблице, а затем использовать ее для запроса используемых индексов, просматривая статистику использования индекса.

Извините, что я не могу привести вам практический пример, просто теоретический пример ...

0 голосов
/ 12 февраля 2010

В студии управления SQL вы можете точно увидеть, как выполняется запрос, используя опцию «Показать план выполнения» в меню «Запрос».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...