사용하지 않은 저장 프로 시저 식별 사용되는 것으로 추정되므로 많은 작업이

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

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

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

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

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



답변

당신이 사용할 수있는 서버 측 추적 하여 테스트 또는 비즈니스주기 캡처 동안 만 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;

인용하다 :


답변

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

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


답변

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그것이 그 여론 조사이 모든 너무 자주 무언가를 설정하기 위해 최선을 다하고 영구 저장소에 저장 할 수 있도록 전용 메모리입니다.


답변

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


답변

이 게시물은 또한 사용하지 않는 개체를 찾기위한 스크립트를 제공합니다. 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


답변