मेरे पास एक संग्रहीत प्रक्रिया है जहां एक मुख्य फ़ील्ड के साथ आधार तालिका को पॉप्युलेट करता है और फिर उस तालिका के माध्यम से लूप करता है ताकि उन महत्वपूर्ण फ़ील्ड को विस्तृत गणना प्राप्त करने के लिए स्रोत डेटा तालिका की आवश्यकता हो। मेरे पास जो मुद्दा है वह यह है कि जब बेस टेबल में बहुत सारी पंक्तियाँ होती हैं, तो एसपी को चलने में लंबा समय लगता है। मैंने स्रोत डेटा को अस्थायी तालिकाओं में लोड किया है और सूचकांक बनाया है और आधार तालिका को एक सूचकांक के साथ एक अस्थायी तालिका भी बनाया है।

CREATE TABLE #SupplementalData1 
(
    ROWID int IDENTITY(1, 1),
    LOB varchar(100),
    Program varchar(100),
    Project varchar(100),
    Container varchar(255),
    RPTNG_Week date,
    Scheduled_Open int,
    Still_Open int,
    Scheduled_Closed int,
    Actual_Closed int
);

CREATE INDEX t1
ON #SupplementalData1 (LOB, Program, Project, Container, RPTNG_Week);

INSERT INTO #SupplementalData1 (LOB, Program, Project, Container, RPTNG_Week)
    SELECT DISTINCT
        a.LOB_CODE,
        a.PRGRM_NAME,
        a.PRJCT_NAME,
        a.CNTNR_NAME,
        b.Monday
    FROM 
        #data a,
        Schedule_Date_Lookup b
    WHERE 
        b.Monday >= @MinMonday
        AND b.Monday <= @MaxMonday
    ORDER BY 
        a.LOB_CODE,
        a.PRGRM_NAME,
        a.PRJCT_NAME,
        b.Monday;

DELETE FROM #SupplementalData1
WHERE RPTNG_Week > @EndDate;

-- Get the number of rows in the looping table
DECLARE @RowCount int;
SET @RowCount = (SELECT COUNT(ROWID)FROM #SupplementalData1);

-- Declare an iterator
DECLARE @I int;
-- Initialize the iterator
SET @I = 1;
--Declare Common Variables
DECLARE @iLOB varchar(MAX),
        @iProgram varchar(MAX),
        @iProject varchar(MAX),
        @iContainer varchar(MAX),
        @iRPTNG_Week date,
        @Value int;

-- Loop through the rows of a table @myTable
WHILE (@I <= @RowCount)
BEGIN

    -- Declare variables to hold the data which we get after looping each record 

    -- Get the data from table and set to variables
    SELECT @iLOB = LOB,
           @iProgram = Program,
           @iProject = Project,
           @iContainer = Container,
           @iRPTNG_Week = RPTNG_Week
    FROM #SupplementalData1
    WHERE ROWID = @I;

    SET @Value = (SELECT COUNT(CNTNR_NAME) AS Scheduled_Open_Sum
                  FROM #data c
                  WHERE (c.NEED_DATE >= @iRPTNG_Week)
                    AND c.LOB_CODE = @iLOB
                    AND c.PRGRM_NAME = @iProgram
                    AND c.PRJCT_NAME = @iProject
                    AND c.CNTNR_NAME = @iContainer);

    UPDATE #SupplementalData1
    SET Scheduled_Open = @Value
    WHERE LOB = @iLOB
      AND Program = @iProgram
      AND Project = @iProject
      AND Container = @iContainer
      AND RPTNG_Week = @iRPTNG_Week;


    -- -- Increment the iterator
    SET @I = @I + 1;

END;

क्या कोई वैकल्पिक तरीका है जो गति में सुधार करेगा?

-1
FlyFish 16 सितंबर 2021, 16:57
मुझे लगता है, अगर आप कुछ नमूना डेटा और वांछित आउटपुट प्रदान करते हैं तो आपकी मदद करना आसान होगा (तर्क के स्पष्टीकरण के साथ हो सकता है)
 – 
Sergey
16 सितंबर 2021, 16:59
4
किक करने की बुरी आदतें : पुराने का उपयोग करना- स्टाइल जॉइन - पुरानी शैली टेबल की अल्पविराम से अलग की गई सूची शैली को ANSI-उचित ANSI JOIN सिंटैक्स से बदल दिया गया था >92 SQL मानक (लगभग 30 वर्ष पहले) और इसके उपयोग को हतोत्साहित किया जाता है
 – 
marc_s
16 सितंबर 2021, 17:02
1
इस तरह से एकत्रित डेटा को संग्रहीत करना शायद ही कभी एक अच्छा विचार है। जैसे ही आप इस डेटा को सहेजते हैं यह पुराना हो जाता है। जब आपको इसकी आवश्यकता होती है तो इसे संग्रहीत करने के बजाय गिनती क्यों नहीं मिलती?
 – 
Sean Lange
16 सितंबर 2021, 17:20
- आप सही कह रहे हैं मैं जुड़ने के पुराने अंदाज में फंस गया हूं। पुरानी आदतों को तोड़ना मुश्किल है। मुझे बस स्विच ओवर करना है। बट में किक के लिए धन्यवाद।
 – 
FlyFish
16 सितंबर 2021, 17:54
- मैं समेकित डेटा संग्रहीत नहीं कर रहा हूं। रनटाइम पर चार्ट बनाने के लिए यह क्वेरी का एक छोटा सा हिस्सा है। डेटा गैर-एकत्रित संग्रहीत किया जाता है। हालांकि एकत्रित डेटा संग्रहीत करने के बारे में मैं आपके कथन से सहमत हूं।
 – 
FlyFish
16 सितंबर 2021, 17:56

1 उत्तर

सबसे बढ़िया उत्तर

नमूना डेटा, वांछित आउटपुट और आपके तर्क के बिना निम्नलिखित का परीक्षण नहीं किया गया था, लेकिन आपको सही दिशा में आगे बढ़ना चाहिए।

पूरे समय के बयान से दूर रहें और एक सेट आधारित दृष्टिकोण के साथ जाएं।

यहाँ जबकि लूप को SELECT के रूप में फिर से लिखा गया है। मैं आमतौर पर डेटा को दोबारा जांचने और मान्य करने के लिए पहले ऐसा करूंगा।

SELECT      *
FROM        [#SupplementalData1] [supdata]
CROSS APPLY (
                SELECT COUNT([CNTNR_NAME]) AS [Scheduled_Open_Sum]
                FROM   [#data] [c]
                WHERE  [c].[NEED_DATE] >= [supdata].[RPTNG_Week]
                       AND [c].[LOB_CODE] = [supdata].[LOB]
                       AND [c].[PRGRM_NAME] = [supdata].[Program]
                       AND [c].[PRJCT_NAME] = [supdata].[Project]
                       AND [c].[CNTNR_NAME] = [supdata].[Container]
            ) AS [cd];

फिर एक बार जब आप सत्यापित कर लेते हैं कि यह सही है तो आप आसानी से फिर से लिख सकते हैं जिसमें एक अपडेट है। जो आपके लूप को बदल देगा।

UPDATE      [supdata]
SET         [Scheduled_Open] = [cd].[Scheduled_Open_Sum]
FROM        [#SupplementalData1] [supdata]
CROSS APPLY (
                SELECT COUNT([CNTNR_NAME]) AS [Scheduled_Open_Sum]
                FROM   [#data] [c]
                WHERE  [c].[NEED_DATE] >= [supdata].[RPTNG_Week]
                       AND [c].[LOB_CODE] = [supdata].[LOB]
                       AND [c].[PRGRM_NAME] = [supdata].[Program]
                       AND [c].[PRJCT_NAME] = [supdata].[Project]
                       AND [c].[CNTNR_NAME] = [supdata].[Container]
            ) AS [cd];
2
Tim Mylott 16 सितंबर 2021, 17:19
1
उत्तम! शीघ्र जवाब देने के लिए ध्न्यवाद। मैंने बहुत से सेट आधारित प्रश्नों का उपयोग नहीं किया है। यह एक एसपी ले गया जिसे मैंने 10 मिनट के बाद 7 सेकंड में खत्म करने के लिए मार डाला। मेरे शस्त्रागार में एक नया उपकरण।
 – 
FlyFish
16 सितंबर 2021, 17:50