6

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

मैं इस प्रकार इस ROW_NUMBER का उपयोग कर सकते हैं:

WITH TempTable AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY Machine_ID ORDER BY Date_Time) AS Ordering 
    FROM dbo.DataTable 
) 

SELECT [Current].*, Previous.Date_Time AS PreviousDateTime 
FROM TempTable AS [Current] 
INNER JOIN TempTable AS Previous 
    ON [Current].Machine_ID = Previous.Machine_ID 
    AND Previous.Ordering = [Current].Ordering + 1 

समस्या है, यह वास्तव में धीमी गति से (कई मिनट एक मेज पर 10k के बारे में प्रविष्टियों के साथ) चला जाता है - मैं Machine_ID और पर अलग indicies बनाने की कोशिश की डेट_Time, और एक एकल जुड़ाव सूचकांक, लेकिन कुछ भी मदद करता है।

क्या इस प्रश्न को फिर से लिखने के लिए फिर से लिखना है?

उत्तर

5

कैसे यह इस संस्करण ?:

SELECT x.* 
    ,(SELECT MAX(Date_Time) 
     FROM dbo.DataTable 
     WHERE Machine_ID = x.Machine_ID 
      AND Date_Time < x.Date_Time 
    ) AS PreviousDateTime 
FROM dbo.DataTable AS x 
की तुलना

या यह संस्करण ?:

SELECT x.* 
    ,triang_join.PreviousDateTime 
FROM dbo.DataTable AS x 
INNER JOIN (
    SELECT l.Machine_ID, l.Date_Time, MAX(r.Date_Time) AS PreviousDateTime 
    FROM dbo.DataTable AS l 
    LEFT JOIN dbo.DataTable AS r 
    ON l.Machine_ID = r.Machine_ID 
     AND l.Date_Time > r.Date_Time 
    GROUP BY l.Machine_ID, l.Date_Time 
) AS triang_join 
ON triang_join.Machine_ID = x.Machine_ID 
    AND triang_join.Date_Time = x.Date_Time 

दोनों मशीन_आईडी, डेट_Time और सही परिणामों के लिए एक इंडेक्स के साथ सर्वश्रेष्ठ प्रदर्शन करेंगे, मुझे लगता है कि यह अद्वितीय है।

आपने उल्लेख नहीं किया है कि * में क्या छिपा हुआ है और कभी-कभी मशीन_आईडी के बाद से बहुत कुछ इसका मतलब हो सकता है, डेटटाइम इंडेक्स आम तौर पर कवर नहीं होगा और यदि आपके पास बहुत सारे कॉलम हैं या उनके पास बहुत अधिक डेटा है, ...

+0

दूसरी क्वेरी मिनटों के बजाय सेकंड में समाप्त होती है, लेकिन पहली क्वेरी जितनी जल्दी हो सकती है उससे अधिक तेज़ी से निष्पादित होती है। बहुत बहुत धन्यवाद! –

7

दिया ROW_NUMBER() विभाजन और व्यवस्था (Machine_ID, Date_Time) पर एक सूचकांक की आवश्यकता होती है एक पास में पूरा करने के:

CREATE INDEX idxMachineIDDateTime ON DataTable (Machine_ID, Date_Time); 

Machine_ID और DATE_TIME पर अलग अनुक्रमित, थोड़ा में मदद मिलेगी, यदि कोई हो।

+0

जैसा कि मैंने कहा, मैंने उस इंडेक्स को भी बनाया है, और इससे क्वेरी प्रदर्शन में सुधार नहीं हुआ है। –

+4

ऐसा इसलिए है क्योंकि आपका * इंडेक्स टिपिंग पॉइंट ट्रिगर करता है। इसे केवल आवश्यक स्तंभों तक सीमित करें और उपयोग न करें गैर-क्लस्टर किए गए इंडेक्स को कवर करें। यदि बहुत से कॉलम की आवश्यकता है, तो इसे सभी परिणामों के साथ क्लस्टर इंडेक्स में बदलना होगा। –

+0

आप सही होने लगते हैं, * को हटाने से * कुछ सेकंड तक क्वेरी का समय कम हो जाता है। मैं कल्पना नहीं कर सकता कि ऐसा क्यों होगा - क्या आप किसी भी इंडेक्स टिपिंग पॉइंट * के रूप में कोई लिंक प्रदान कर सकते हैं? –

0

क्या होगा यदि आप अंतिम टाइमस्टैम्प को प्रत्येक बार एक अंतर घटाने के लिए ट्रिगर का उपयोग करते हैं तो अंतर प्राप्त करने के लिए?

+0

दुर्भाग्य से, यह ऐतिहासिक डेटा है, और क्रम में हमेशा जोड़ा नहीं जाता है। –

2

SQL सर्वर 2005 में सीटीई का उपयोग करके मुझे कुछ अजीब प्रदर्शन समस्याएं आई हैं। कई मामलों में, सीटीई को वास्तविक अस्थायी तालिका के साथ बदलकर समस्या हल हो गई।

मैं सीटीई का उपयोग करने के साथ आगे जाने से पहले इसे आजमाउंगा।

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

अद्यतन

अपनी टिप्पणी है कि यह एक दृश्य है के बाद, मैं पहली बार एक अस्थायी तालिका के साथ क्वेरी है कि अगर बेहतर प्रदर्शन करती है यह देखने के लिए परीक्षण होगा।

यदि ऐसा होता है, और संग्रहीत प्रो का उपयोग करना एक विकल्प नहीं है, तो आप वर्तमान सीटीई को अनुक्रमित/भौतिक दृश्य में बनाने पर विचार कर सकते हैं। आप इस सड़क पर जाने से पहले इस विषय पर पढ़ना चाहेंगे, जैसे कि यह एक अच्छा विचार है, कई कारकों पर निर्भर करता है, जिनमें से कम से कम डेटा अपडेट नहीं किया जाता है।

+0

मैं यह कैसे करूँगा? क्या मुझे दृश्य को एक स्पोक के साथ प्रतिस्थापित करने की आवश्यकता होगी (क्योंकि विचारों में चर नहीं हो सकते हैं)? –

+0

हां, मुझे स्पष्ट नहीं था कि यह आपके प्रश्न से एक दृश्य था। मेरे उत्तर में अपडेट देखें (कुछ मिनटों में पालन करेंगे)। –

0

यदि आपको डेटा को खींचने पर हर बार गणना करने की बजाय आपको अक्सर इस डेटा की आवश्यकता होती है, तो कॉलम क्यों न जोड़ें और जब भी पंक्ति जोड़ दी जाए तो उसे गणना/पॉप्युलेट करें?

(Remus 'यौगिक सूचकांक क्वेरी तेज कर देगा;। यह केवल एक बार चल रहा है यह तेजी से अभी भी बनाना चाहिए)

4

dbo.DataTable में पंक्तियों की संख्या बड़ी है, तो यह संभव है कि आप का सामना कर रहे है खुद को शामिल होने वाले सीटीई स्वयं के कारण जारी करें।कुछ विवरणों में इस मुद्दे को समझाते हुए एक ब्लॉग पोस्ट है here

कभी-कभी ऐसे मामलों में मैंने सीटीई क्वेरी के परिणाम को सम्मिलित करने के लिए एक अस्थायी तालिका बनाने का प्रयास किया और फिर उस अस्थायी तालिका के खिलाफ जुड़ने के लिए (हालांकि इसमें आमतौर पर ऐसे मामलों में जहां अस्थायी तालिका के विरुद्ध मिलती है की एक बड़ी संख्या के लिए आवश्यक हैं के लिए किया गया - एक में शामिल होने के प्रदर्शन अंतर के मामले में कम उल्लेखनीय हो जाएगा)

+1

मैं इस दृष्टिकोण को दूसरा करता हूं। सीटीई बस इनलाइन रीराइट्स हैं। अपने कोड को दोहराने और स्वयं-जुड़ने की तरह, गारंटी देने के लिए कुछ भी नहीं है कि अनुकूलक इसे अस्थायी तालिका में घुमाएगा। यदि आप अपनी खुद की मेज में चीजें डालते हैं, तो आप इंडेक्स चुन सकते हैं और/या डबल काम से बच सकते हैं। ऐसा कहकर, मैं सीटीई का उपयोग करता हूं जहां कोड रखरखाव महत्वपूर्ण है और जहां स्कीमा बहुत तेज़ी से बदलने के लिए उत्तरदायी है (या विचारों में, इस मामले की तरह)। –