2010-03-10 12 views
6

के लिए इंडेक्स किए गए व्यू पर धीमापन कहें कि मेरे पास टाइमकार्ड नामक एक बहुत लंबी तालिका (~ 35 मिलियन पंक्तियां) है जिसमें केवल 5 कॉलम (टेबलआईडी, कंपनीआईडी, यूजरआईडी, प्रोजेक्टआईडी, डेलीहॉर्ड्स वर्कड, एंट्रीडेट) हैं। यह एक बहुत सीधी अगली तालिका है जो प्रति कंपनी प्रति परियोजना कर्मचारियों के कामकाजी घंटे प्रति दिन रिकॉर्ड करती है।एसक्यूएल 2005

अब मुझे किसी भी कंपनी के लिए प्रति माह कर्मचारियों के कुल कार्य घंटे प्रति माह पता लगाने के लिए एक रिपोर्ट तैयार करने की आवश्यकता है। रिपोर्ट चलने पर आवश्यक एकत्रीकरण करने के बजाय, मैं एक टेबल जैसी डेटा संरचना बनाना चाहता हूं जिसमें पहले से ही सभी कंपनी/परियोजना/उपयोगकर्ता डेटा एकत्रित हो, इसलिए जब रिपोर्ट चलती है, तो मैं सीधे उस डेटा संरचना से पूछताछ कर सकता हूं ~ 35 मिलियन रिकॉर्ड के बाद से कुछ रन-टाइम एकत्रीकरण किए बिना कुछ मिनट लग सकते हैं।

तो मेरे पास 2 अलग-अलग तरीके हैं। एक मेरे अतिरिक्त कॉलम के रूप में (CompanyID, UserID, ProjectID, MonthlyHoursWorked, Month) के साथ एक अतिरिक्त भौतिक तालिका बनाएं और अतिरिक्त तालिका में मानों को संशोधित करने के लिए टाइमकार्ड तालिका पर ट्रिगर का उपयोग करें। या मैं एक अनुक्रमित दृश्य बना सकते हैं। तो मैंने दोनों की कोशिश की। मैंने पहले निम्नलिखित कोड के साथ अनुक्रमित दृश्य की कोशिश की:

CREATE VIEW [dbo].[vw_myView] WITH SCHEMABINDING AS 
SELECT 
JobID, 
ProjectID, 
Sum(DailyHoursWorked) AS MonthTotal, 
DATEADD(Month, DATEDIFF(Month, 0, entryDate), 0) AS entryMonth, 
CompanyID, 
COUNT_BIG(*) AS Counter 
FROM 
dbo.TimeCard 
Group By DATEADD(Month, DATEDIFF(Month, 0, entryDate), 0), JobID, ProjectID, CompanyID 

Go 
CREATE UNIQUE CLUSTERED INDEX [IX_someIndex] ON [dbo].[vw_myView] 
(
[CompanyID] ASC, 
[entryMonth] ASC, 
[UserID] ASC, 
[ProjectID] ASC 
) 

अनुक्रमित दृश्य सही ढंग से बनाया गया और कुल ~ 5 मिलियन पंक्तियों के साथ कुल मिलाकर।

हालांकि, हर बार यदि मैं SQL कैश साफ़ करता हूं, और निम्न क्वेरी चलाता हूं: * vw_myView से * चुनें * जहां कंपनी आईडी = 1 *, इसमें लगभग 3 मिनट लगते हैं। यदि मैं ऊपर वर्णित अतिरिक्त तालिका मार्ग के साथ जाता हूं, तो मेरे कैश को साफ़ करने के साथ, इसमें लगभग 4 सेकंड लगते हैं।

मेरे प्रश्न हैं, इंडेक्स किया गया है इस विशेष परिदृश्य के लिए एक खराब विकल्प देखें? विशेष रूप से मुझे यह जानने में दिलचस्पी है कि क्या संपूर्ण अनुक्रमित दृश्य को हर बार फिर से गणना/पुन: एकत्रित किया जाता है जब अंतर्निहित तालिका (टाइमकार्ड) बदल जाती है या जब कोई क्वेरी इसके खिलाफ चलती है?

धन्यवाद!

+0

SQL सर्वर 2005 का आप किस संस्करण का उपयोग कर रहे हैं? – RedFilter

+0

आपके 'एंट्री मॉन्थ' में महीने के पहले दिन की पूरी तिथि होने के बजाय, क्या आपके पास अभी तक 'माह (एंट्रीडेट)' और संभवतः 'वर्ष (एंट्रीडेट)' नहीं हो सकता है? मेरे लिए बहुत आसान लगता है (लेकिन फिर से - मुझे आपकी सटीक आवश्यकताओं को नहीं पता) .... –

उत्तर

0

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

+1

ट्रिगर्स बहुत तेज़ नहीं हैं। –

+0

विचार अक्सर ट्रिगर से धीमे होते हैं (विशेष रूप से यदि आप उन्हें एक-दूसरे के ऊपर ढेर करते हैं) और एक ट्रिगर को तेज़ होने के लिए ठीक से लिखा जा सकता है। – HLGEM

2

आप प्रयोग नहीं कर रहे हैं, तो या तो उद्यम या डेवलपर संस्करण है, तो आप with (noexpand) संकेत उपयोग करने की आवश्यकता: जब अंतर्निहित डेटा परिवर्तन, केवल देखने के लिए से संबंधित पंक्तियों अद्यतन करेगा

select * 
from vw_myView with (noexpand) 
where companyID = 1 

परिवर्तित डेटा, पूरी तालिका नहीं। इसका उच्चतर आवेषण वाले ओएलटीपी डेटाबेस पर प्रतिकूल प्रभाव पड़ सकता है, लेकिन यदि उपयोग केवल मध्यम है, तो प्रदर्शन समस्या उत्पन्न नहीं करनी चाहिए।

एक tip from Microsoft:

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

+0

मुझे क्या नहीं मिलता है, यदि मैं कैश साफ़ करता हूं और बेस टेबल मान में से कोई भी बदल नहीं गया है तो एक साधारण क्वेरी के लिए 3 मिनट क्यों लगते हैं। क्या यह वास्तव में फिर से पूरे एकत्रीकरण कर रहा है? – TheYouth

+0

@TheYouth: क्या आपने '(noexpand) संकेत के साथ प्रयास किया था? – RedFilter

+1

+1 यदि आप SQL सर्वर के EXPRESS या DEVELOPER संस्करणों के साथ (NOEXPAND) जोड़ना भूल जाते हैं तो ऑप्टिमाइज़र अनुक्रमित दृश्य का उपयोग नहीं करेगा लेकिन अंतर्निहित तालिकाओं से चयन करेगा। –

0

मुझे नहीं लगता कि आपको अनुक्रमित दृश्य की आवश्यकता है (मैं नहीं कहता, अनुक्रमित दृश्य खराब/अच्छा विचार है)। मुझे लगता है, आपको "कंपनी आईडी" और "एंट्रीडेट" कॉलम पर इंडेक्स चाहिए।उसके बाद आपको कहां उपयोग करना चाहिए "जहां कंपनी आईडी = @ कॉम्पैनीड और एंट्रीडेट> = @ स्टार्टडेट और एंट्रीडेट < = @ एंडडेट"।

यदि तालिका "एंट्रीडेट" द्वारा प्राथमिक रूप से संसाधित की जाती है, तो आप "एंट्रीडेट" कॉलम पर क्लस्टर इंडेक्स का उपयोग कर सकते हैं।

इसके बाद, मुझे लगता है कि चयन कथन अब बहुत तेज होगा।

+1

दृश्य पर क्लस्टरेड इंडेक्स पहले से ही कंपनीआईडी ​​को अपने पहले कॉलम के रूप में उपयोग करता है - जो वास्तव में चाल करना चाहिए। मुझे इंडेक्स में कोई लाभ नहीं दिख रहा है (CompanyID, EntryDate) - EntryDate का उपयोग करके कोई प्रश्न नहीं प्रतीत होता है, तो इसे अनुक्रमणित करने का क्या मतलब है? –

+0

टाइमकार्ड को एंट्रीडेट, कंपनीआईडी, यूजरआईडी, प्रोजेक्टआईडी, सभी अलग गैर-क्लस्टर इंडेक्स में अनुक्रमित किया गया है। मुझे जो नहीं मिलता है वह है कि यदि मैं कैश साफ़ करता हूं तो एक साधारण क्वेरी के लिए 3 मिनट लगते हैं। क्या यह वास्तव में फिर से पूरे एकत्रीकरण कर रहा है? – TheYouth

+0

आपने इसे EntryDate द्वारा फ़िल्टर किया था। यदि आप जानते हैं, तो आपके पास जनवरी 2010 के बारे में पहले से ही एक समेकित जानकारी है, आपको प्राथमिक तालिका से फिर से चयन टीआई की आवश्यकता नहीं है। यदि आप "एंट्रीडेट" कॉलम (कंपनी आईडी के बिना) पर क्लस्टर इंडेक्स का उपयोग करते हैं - आपको इस कॉलम के आधार पर चयन के लिए बेहतर प्रदर्शन करना चाहिए। – TcKs

1

मुझे लगता है कि आप इंडेक्स व्यू का उपयोग करने के साथ सही रास्ते पर हैं। हालांकि, क्या आपने अपने कुल कॉलम के लिए TimeCard से पूछताछ कर रहे टेबल पर इंडेक्स लगाए हैं। आपको JobID, ProjectID, entryDate, CompanyID (1 अनुक्रमणिका) का सूचकांक बनाना होगा। यदि आप प्रत्येक कॉलम के लिए 1 इंडेक्स का उपयोग करते हैं तो यह आपकी समस्याओं का समाधान नहीं करेगा क्योंकि क्वेरी को सभी 4 इंडेक्स का एक साथ उपयोग करना होगा।

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

+2

मुझे नहीं लगता कि अधिक अनुक्रमणिका कैसे मददगार होंगी, क्वेरी 'कंपनी आईडी' द्वारा चुनी जा रही है, जो पहले ही अनुक्रमित है। – RedFilter

+0

टाइमकार्ड को एंट्रीडेट, कंपनीआईडी, यूजरआईडी, प्रोजेक्टआईडी, सभी अलग गैर-क्लस्टर इंडेक्स में अनुक्रमित किया गया है। मुझे जो नहीं मिलता है वह है कि यदि मैं कैश साफ़ करता हूं तो एक साधारण क्वेरी के लिए 3 मिनट लगते हैं। क्या यह वास्तव में फिर से पूरे एकत्रीकरण कर रहा है? – TheYouth

+0

मुझे लगता है कि यह है। हालांकि, मुझे लगता है कि अगर आपके पास प्रविष्टिडेट, कंपनीआईडी, यूजरआईडी, प्रोजेक्टआईडी के लिए 1 गैर-क्लस्टर इंडेक्स था तो यह बेहतर होगा। 4 इंडेक्स होने के बाद, उनमें से प्रत्येक कॉलम के लिए एक वास्तव में आपकी मदद करने वाला नहीं है क्योंकि आपका समूह सभी 4 का एक साथ उपयोग कर रहा है। तो आप 1 इंडेक्स चाहते हैं जिसमें इसमें सभी 4 कॉलम हों। –

0

क्या आपने तालिका को विभाजित करने पर विचार किया था। आप सूची और हैश विभाजन तालिका के संयोजन के बारे में सोच सकते हैं।

0

ठीक है, अनुक्रमित दृश्य का विचार निश्चित रूप से अच्छा है, और यदि आप उस पर क्लस्टर्ड इंडेक्स बना सकते हैं - सही। यह तेज़ होना चाहिए - एक प्रश्न के लिए 3 मिनट से भी बेहतर!

दूसरी तरफ: यदि जानकारी के उन हिस्सों को केवल अपडेट किया गया है उदा। महीने में या एक बार साप्ताहिक (या यहां तक ​​कि हर रात), एक बार उन्हें अलग DailyTimeCard तालिका में रखना बेहतर हो सकता है जो उदा। नियमित रूप से एक एसएसआईएस पैकेज।

मैं चलाता का उपयोग कर लगातार इस तरह के एक तथ्य तालिका अद्यतन करने के लिए सिफारिश नहीं होगा या तो - अगर आप वास्तव में बहुत हर दिन में दूसरा दिया पर तिथि के आंकड़ों के ऊपर सबसे की आवश्यकता है, तो अनुक्रमित दृश्य के साथ रहते हैं।

लेकिन, आपका अनुक्रमित दृश्य भारी भारोत्तोलन करता है - यह बताता है, यह समूह द्वारा और इसी तरह से होता है। इसे हर समय अद्यतित रखते हुए, जबकि आपकी अंतर्निहित TimeCard तालिका बदलती है और अपडेट हो जाती है, आपके सिस्टम पर कुछ लोड का कारण बनता है - यह कहना मुश्किल है - लेकिन यह काफी ध्यान देने योग्य हो सकता है।

यदि आपको आवश्यक जानकारी निकालने का कोई तरीका मिलता है - समूह और योग एक बार और फिर उस समेकित डेटा को एक अलग तथ्य तालिका में संग्रहीत करें - आपके पास दोनों होना चाहिए: DailyTimeCard तालिका पर शेष और त्वरित प्रश्न, और शेष अनुक्रमित दृश्य को हर समय अद्यतित रखने के साथ आपकी प्रणाली को कम बोझ होना चाहिए।

शायद यह वह समाधान नहीं है जिसे आप ढूंढ रहे हैं - लेकिन बस इसके बारे में सोचें। यह हो सकता है - या शायद नहीं - आपके लिए काम करना!

संबंधित मुद्दे