사용하지 않은 저장 프로 시저 식별


24

내년에는 여러 SQL Server 환경을 정리하려는 노력을 돕고 있습니다.

약 10,000 개의 저장 프로 시저가 있으며 그 중 약 1000 개만 정기적으로 사용되고 거의 200 개 정도가 드물게 사용되는 것으로 추정되므로 많은 작업이 필요합니다.

이러한 데이터베이스와 프로 시저에 액세스 할 수있는 여러 부서와 팀이 있기 때문에 항상 프로 시저를 호출하는 것은 아니며, 어떤 프로 시저를 호출해야하는지 결정해야합니다. 또한 며칠이 아닌 며칠 동안 (몇 가지 가능성을 제거함)이를 결정하려고합니다.

이에 대한 한 가지 접근 방식 SQL Server Profiler은 호출 된 프로 시저 를 사용 하고 추적하여 프로 시저의 사용 여부를 표시하면서 해당 프로 시저 목록과 비교하는 것입니다. 그때부터 부서가 비명을 지르는 경우 절차를 다른 스키마로 옮길 수있었습니다.

Profiler가장 효과적인 방법을 사용하고 있습니까? 그리고 / 혹은 비슷한 일을하고 다른 방법 / 더 나은 방법을 찾은 적이 있습니까?

답변:


32

당신이 사용할 수있는 서버 측 추적 하여 테스트 또는 비즈니스주기 캡처 동안 만 SP의 관련 물건 (초래 더 많은 자원이 있음을 프로파일 러 GUI를 사용하여 다른 참조). 그런 다음 테이블에로드하거나 추가 분석을 위해 Excel을 사용할 수 있습니다.

두 번째 방법은 DMV sys.dm_exec_procedure_stats 를 사용 하는 것입니다 (SQL 서버를 다시 시작하면 데이터가 플러시된다는 제한이 있음).

DMV 데이터를 테이블로 캡처하여 유지되도록 작업을 예약 할 수도 있습니다.

 -- Get list of possibly unused SPs (SQL 2008 only)
    SELECT p.name AS 'SP Name'        -- Get list of all SPs in the current database
    FROM sys.procedures AS p
    WHERE p.is_ms_shipped = 0

    EXCEPT

    SELECT p.name AS 'SP Name'        -- Get list of all SPs from the current database 
    FROM sys.procedures AS p          -- that are in the procedure cache
    INNER JOIN sys.dm_exec_procedure_stats AS qs
    ON p.object_id = qs.object_id
    WHERE p.is_ms_shipped = 0;

인용하다 :


1
또한 stackoverflow.com/questions/10421439/…stackoverflow.com/questions/7150900/…을 참조하십시오 (후자는 SQLServerPedia에 대한 링크가 이제 무시 됨).
Aaron Bertrand

2
SP는 매월 또는 분기별로 실행되는 SP가있을 수 있으므로 몇 주 또는 몇 달 동안 정기적으로 DMV를 확인하십시오. 인스턴스가 재시작 될 때 DMV가 지워지고 수동으로 지워지거나 시간이 지남에 따라 지워집니다.
케네스 피셔

1
@KennethFisher 그렇기 때문에 DMV 데이터를 테이블에 캡처하는 작업을 예약하는 것이 좋습니다. 그래도 언급 해 주셔서 감사합니다!
Kin Shah

11

이 질문이 유용하다는 것을 알 수 있습니다. 표와 열에 적용되지만 타사 도구 ApexSQL Clean을 사용하여 사용하지 않는 저장 프로 시저와 데이터베이스 또는 외부 데이터베이스의 다른 개체에서 참조하지 않는 모든 개체를 찾을 수도 있습니다.

면책 조항 : ApexSQL에서 지원 엔지니어로 일하고 있습니다.


3
OP는 찾기 unreferenced stored procedures를 원하지 않고 대신 사용되지 않은 SP를 찾기를 원합니다. 귀하의 답변은이 질문에 대한 답변이 아닙니다.
Kin Shah

나는 업데이트 할 것이다. ApexSQL Clean은 사용하지 않는 개체를 참조되지 않은 것으로 표시하므로 혼동을 일으킨 것으로 이해합니다
Milica Medic

10

SQL Server 2008+를 사용하는 경우 히스토그램 대상 과 함께 확장 이벤트를 사용할 수도 있습니다 . 아마도 이것은 흔적보다 더 가벼울 것입니다.

AFAIK에서는 여러 열에 대한 버킷 화가 가능하다는 표시를 볼 수 없으므로 관심있는 각 데이터베이스마다 다른 세션을 만들어야합니다. 아래의 빠른 예는database_id=10

CREATE EVENT SESSION [count_module_start_database_10]
ON SERVER
ADD EVENT sqlserver.module_start
(  
        WHERE (source_database_id=10) 
)
ADD TARGET package0.asynchronous_bucketizer
(     SET  filtering_event_name='sqlserver.module_start', 
            source_type=0, 
            source='object_id',
            slots = 10000
)
WITH (MAX_DISPATCH_LATENCY = 5 SECONDS)
GO
ALTER EVENT SESSION [count_module_start_database_10]
ON SERVER
STATE=START

그런 다음 해당 DB에서 일부 스토어드 프로 시저를 몇 번 실행하고 다음을 사용하여 데이터를 검색 한 후

SELECT CAST(target_data as XML) target_data
FROM sys.dm_xe_sessions AS s 
JOIN sys.dm_xe_session_targets t
    ON s.address = t.event_session_address
WHERE s.name = 'count_module_start_database_10'

출력은

<HistogramTarget truncated="0" buckets="16384">
  <Slot count="36">
    <value>1287675635</value>
  </Slot>
  <Slot count="3">
    <value>1271675578</value>
  </Slot>
  <Slot count="2">
    <value>1255675521</value>
  </Slot>
</HistogramTarget>

함께 보여주는 절차 object_id의가 1287675635예를 들어 36 회 실행 하였다. 는 asynchronous_bucketizer그것이 그 여론 조사이 모든 너무 자주 무언가를 설정하기 위해 최선을 다하고 영구 저장소에 저장 할 수 있도록 전용 메모리입니다.


1
데이터베이스 당 하나의 세션이 필요합니다. 말할 수는 WHERE (source_database_id IN (10,15,20))있지만 슬프게도 지원되지 않습니다.
Aaron Bertrand

@AaronBertrand-지원 되더라도 다른 데이터베이스에서 동일한 object_id(또는 같은 object_name) 객체에 대한 프로 시저 호출을 별도로 계산해야하며 가능하다고 생각하지 않습니다.
Martin Smith

메신저가 잘못되었지만 extended events2008 년이 아닌 2012 년에 추가 된 위치를 수정 하시겠습니까?
Peter

1
@Peter yep 당신이 틀 렸습니다. :-) technet.microsoft.com/en-us/library/dd822788(v=sql.100).aspx
Martin Smith

1
확장 이벤트 UI는 SSMS 2012까지 소개되지 않았으며 이전 버전과 호환되지 않았다고 생각합니다. 비슷한 기능을위한 커뮤니티 프로젝트가 있었지만 2008 상자 밖으로 세션을 만들 수있는 유일한 방법은 TSQL을 통해서였다 extendedeventmanager.codeplex.com
마틴 스미스

4

Kin의 스크립트에 따라. 다음은 시간이 지남에 따른 사용을 추적하는 테이블을 생성하는 간단한 스크립트와 정기적으로 업데이트하는 스크립트입니다.

--  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--  Create the use table 
--  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CREATE TABLE [dbo].[_ProcedureUseLog](
    [ObjectName] [nvarchar](255) NOT NULL,
    [UseCount] [int] NULL,
    [LastUse] [datetime] NULL,
    [LastCache] [datetime] NULL,
 CONSTRAINT [PK___PROCEDURE_USE] PRIMARY KEY CLUSTERED 
(
    [ObjectName] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[_ProcedureUseLog] ADD  CONSTRAINT [DF_Table_1_References]  DEFAULT ((0)) FOR [UseCount]
GO

--  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--  Run this periodically to update the usage stats
--  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DECLARE @UsesTable TABLE
(
    ObjectName nvarchar(255),
    Executions int,
    LastUse datetime,
    LastCache datetime
)

INSERT INTO @UsesTable       
SELECT p.name, qs.execution_count, qs.last_execution_time, qs.cached_time
FROM    sys.procedures AS p LEFT OUTER JOIN
        sys.dm_exec_procedure_stats AS qs ON p.object_id = qs.object_id
WHERE        (p.is_ms_shipped = 0)

MERGE [dbo].[_ProcedureUseLog]      AS [Target]
USING @UsesTable                    AS [Source]
    ON Target.ObjectName = Source.ObjectName
WHEN MATCHED AND 
        ( Target.LastCache <> Source.LastCache)
    THEN UPDATE SET
        Target.UseCount = Target.UseCount + Source.Executions,
        Target.LastCache = Source.LastCache,
        Target.LastUse = Source.LastUse
WHEN NOT MATCHED
    THEN INSERT (ObjectName, UseCount, LastUse, LastCache) 
    VALUES      (ObjectName, Executions, LastUse, LastCache);

--  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--  This just shows what you've logged so far
--  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SELECT * FROM [_ProcedureUseLog] ORDER BY UseCount DESC

0

이 게시물은 또한 사용하지 않는 개체를 찾기위한 스크립트를 제공합니다. SQL Server에서 사용되지 않는 데이터베이스 테이블 찾기 아래는이 기사의 스크립트입니다. 테이블 유형 "U"를 저장 프로 시저 유형 "P"로 변경했습니다.

   USE DBName;
   SELECT 

       ao.[name] [Table],
       s.[name] [Schema],
       [create_date] [Created],
        [modify_date] [LastModified]
    FROM
         sys.all_objects ao JOIN sys.schemas s
           ON ao.schema_id = s.schema_id
    WHERE
         OBJECT_ID NOT IN (
              SELECT OBJECT_ID
              FROM sys.dm_db_index_usage_stats
        )
        AND [type] = 'P'
    ORDER BY
        [modify_date] DESC

이것은 절차가 인덱스 사용 통계 DMV
Martin Smith
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.