अप्रयुक्त संग्रहित प्रक्रियाओं की पहचान करना


24

यह अगले साल, मैं कई SQL सर्वर वातावरण को साफ करने के प्रयास में मदद कर रहा हूं।

हमारे पास लगभग 10,000 संग्रहीत कार्यविधियाँ हैं और अनुमान है कि उनमें से केवल 1000 का उपयोग नियमित आधार पर किया जाता है, और एक और 200 या तो एक दुर्लभ अवसर पर उपयोग किया जाता है, जिसका अर्थ है कि हमारे पास बहुत काम है।

चूंकि हमारे पास कई विभाग और टीमें हैं जो इन डेटाबेस और प्रक्रियाओं तक पहुंच सकते हैं, हम हमेशा प्रक्रियाओं को कॉल करने वाले नहीं होते हैं, जिसका अर्थ है कि हमें यह निर्धारित करना चाहिए कि क्या प्रक्रियाएं कहा जा रहा है। उसके ऊपर, हम इसे कुछ महीनों में निर्धारित करना चाहते हैं, कुछ दिनों में नहीं (जो कुछ संभावनाओं को समाप्त कर देता है)।

इसका एक तरीका यह है SQL Server Profilerकि प्रक्रियाओं का उपयोग किया जा रहा है और ट्रैक करें कि प्रक्रियाओं की प्रक्रिया का उपयोग किया जाता है या नहीं, जबकि यह चिह्नित करते हुए कि उनकी क्या प्रक्रिया है, उनकी सूची से तुलना करें। तब से, हम प्रक्रियाओं को एक अलग स्कीमा में स्थानांतरित कर सकते हैं यदि कोई विभाग चिल्ला रहा है।

Profilerयहां सबसे प्रभावी दृष्टिकोण का उपयोग कर रहा है? और / या आप में से किसी ने भी कुछ ऐसा ही किया है और ऐसा करने का एक और तरीका / बेहतर तरीका पाया है?

जवाबों:


32

आप अपने परीक्षण या अपने व्यापार चक्र के दौरान सर्वर साइड ट्रेस (Profiler GUI का उपयोग करके अधिक संसाधन लगाते हैं ) से भिन्न का उपयोग कर सकते हैं और केवल SP से संबंधित सामान पर कब्जा कर सकते हैं। फिर आप उस तालिका को लोड कर सकते हैं या आगे के विश्लेषण के लिए एक्सेल कर सकते हैं।

दूसरा तरीका, DMV sysinos_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 की लिंक अब मृत है) को देखें।
हारून बर्ट्रेंड

2
सुनिश्चित करें कि आप समय-समय पर या यहां तक ​​कि महीनों तक DMV की समय-समय पर जांच करते रहें क्योंकि ऐसे SPs हो सकते हैं जो केवल मासिक या त्रैमासिक आधार पर चलते हैं। DMV को तब हटा दिया जाता है जब उदाहरण को पुनः आरंभ किया जाता है, मैन्युअल रूप से साफ़ किया जाता है, या केवल समय के साथ।
केनेथ फिशर

1
@KennethFisher यही कारण है कि मैं एक मेज पर DMV डेटा पर कब्जा करने के लिए एक नौकरी अनुसूची की सिफारिश की। हालांकि उल्लेख करने के लिए धन्यवाद!
परिजन शाह

11

आप इस प्रश्न को उपयोगी पा सकते हैं , यह तालिकाओं और स्तंभों पर लागू होता है, लेकिन एक तीसरे पक्ष के टूल एपेक्सक्यूएक्स क्लीन का उपयोग करने का सुझाव देता है, जो अप्रयुक्त संग्रहीत कार्यविधियों के साथ-साथ उन सभी वस्तुओं को भी खोज सकता है जो डेटाबेस में, या बाहरी डेटाबेस में किसी अन्य ऑब्जेक्ट द्वारा संदर्भित नहीं हैं।

अस्वीकरण: मैं एक सहायक अभियंता के रूप में एपेक्सक्यूएल के लिए काम करता हूं


3
ओपी नहीं खोजना चाहता unreferenced stored procedures, इसके बजाय ओपी अप्रयुक्त एसपी को खोजना चाहता है। आपका उत्तर इस प्रश्न के उत्तर के रूप में काम नहीं करता है।
परिजन शाह

परिजन मैं अपडेट करूंगा। ApexSQL साफ निशान अप्रयुक्त वस्तुओं unreferenced के रूप में तो मुझे लगता है कि है कि भ्रम का कारण समझ में
मिलिका चिकित्सक

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

और फिर उस डीबी में कुछ संग्रहीत प्रक्रियाओं को चलाने के बाद कुछ समय और डेटा को पुनः प्राप्त करना

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))लेकिन अफसोस यह समर्थित नहीं है।
हारून बर्ट्रेंड

@AaronBertrand - और यहां तक ​​कि अगर यह समर्थित था तब भी आपको अलग-अलग डेटाबेस में object_idएक ही (या समान object_name) वाली वस्तुओं के लिए प्रक्रिया कॉल की गणना करने की आवश्यकता होगी और मुझे नहीं लगता कि यह संभव भी है।
मार्टिन स्मिथ

मुझे गलत अगर im गलत है, लेकिन extended eventsजहां 2012 में नहीं 2008 में जोड़ा?
पीटर


1
विस्तारित इवेंट UI को SSMS 2012 तक पेश नहीं किया गया था और मुझे नहीं लगता कि उन्होंने इसे पीछे की ओर संगत बनाया है। 2008 को एक ही तरीका है बॉक्स बाहर सत्र बनाने के लिए हालांकि इसी तरह की सुविधा के लिए एक समुदाय परियोजना नहीं थी TSQL के माध्यम से था extendedeventmanager.codeplex.com
मार्टिन स्मिथ

4

परिजनों की पटकथा पर एक अनुसरण के रूप में। समय के साथ उपयोगों को ट्रैक करने के लिए एक तालिका बनाने के लिए एक सरल स्क्रिप्ट है और समय-समय पर इसे अद्यतन करने के लिए एक स्क्रिप्ट।

--  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--  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

यह पोस्ट अप्रयुक्त ojects को खोजने के लिए एक स्क्रिप्ट भी प्रदान करती है: SQL सर्वर में अप्रयुक्त डेटाबेस तालिकाओं को ढूंढें नीचे आलेख से स्क्रिप्ट है, मैंने तालिका प्रकार "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 में प्रविष्टियां नहीं मिलती हैं ...
मार्टिन स्मिथ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.