2009-10-06 11 views
5

मैं एक मेडिकल-रिकॉर्ड सिस्टम के साथ काम कर रहा हूं जो स्प्रेडशीट जैसा दिखता है, कॉलम हेडर में दिनांक/समय, माप (जैसे चिकित्सक का नाम, आरएच, रक्त प्रकार) प्रत्येक पंक्ति के पहले कॉलम में, और अंतरंग सेल में एक मान। इस निर्माण पर आधारित रिपोर्टों को अक्सर प्रदर्शित होने के लिए इनमें से 10 या अधिक उपायों की आवश्यकता होती है।एसक्यूएल सर्वर: इनलाइन टेबल-वैल्यू यूडीएफ बनाम इनलाइन व्यू

रिपोर्टिंग उद्देश्यों के लिए, डेटासेट को प्रत्येक रोगी के लिए एक पंक्ति, माप की तारीख/समय, और प्रत्येक माप के लिए एक कॉलम की आवश्यकता होती है। संक्षेप में, किसी को 9 0 डिग्री से निर्माण करने की जरूरत है।

एक बिंदु पर, मैंने वास्तव में ऐसा करने के लिए SQL सर्वर की PIVOT कार्यक्षमता का उपयोग किया। कई कारणों से, यह स्पष्ट हो गया कि यह दृष्टिकोण काम नहीं करेगा। मैंने फैसला किया कि मैं वांछित प्रारूप में डेटा मालिश करने के लिए एक इनलाइन व्यू (IV) का उपयोग करूंगा। सरलीकृत क्वेरी जैसा दिखता है:

SELECT patient_id, 
     datetime, 
     m1.value AS physician_name, 
     m2.value AS blood_type, 
     m3.value AS rh 
    FROM patient_table 
INNER JOIN (complex query here 
       WHERE measure_id=1) m1... 
INNER JOIN (complex query here 
       WHERE measure_id=2) m2... 
LEFT OUTER JOIN (complex query here 
       WHERE measure_id=3) m3... 

आप देख सकते हैं, कुछ मामलों में इन IVs (भीतरी शामिल हों) जिसके परिणामस्वरूप डाटासेट प्रतिबंधित करने के लिए, अन्य मामलों में वे डाटासेट (बाएं बाहरी शामिल हों) प्रतिबंधित नहीं करते, उपयोग किया जाता है। हालांकि, माप_आईडी में अंतर को छोड़कर, 'जटिल क्वेरी' भाग अनिवार्य रूप से इन मापों में से प्रत्येक के लिए समान है। हालांकि यह दृष्टिकोण काम करता है, यह काफी बड़े SQL कथन, पुन: उपयोग की सीमा का कारण बनता है, और त्रुटियों को क्वेरी का खुलासा करता है।

मेरा विचार 'जटिल क्वेरी' और इनलाइन टेबल-वैल्यू यूडीएफ के साथ WHERE क्लॉज को प्रतिस्थापित करना था। यह प्रश्नों को थोड़ा सा सरल करेगा, त्रुटियों को कम करेगा, और कोड पुन: उपयोग बढ़ाएगा। मेरे दिमाग पर एकमात्र सवाल प्रदर्शन है। क्या यूडीएफ दृष्टिकोण प्रदर्शन में महत्वपूर्ण कमी का कारण बन जाएगा? क्या इससे मामलों में सुधार हो सकता है?

आपके समय और विचार के लिए धन्यवाद।

उत्तर

1

आपके पास तीसरा विकल्प भी है; एक पारंपरिक दृश्य (यह मानते हुए कि आपके पास शामिल होने की कुंजी है)। सिद्धांत रूप में, तीन विकल्पों के बीच प्रदर्शन अंतर नहीं होना चाहिए क्योंकि SQL सर्वर को तदनुसार योजनाओं का मूल्यांकन और अनुकूलन करना चाहिए। वास्तविकता यह है कि कभी-कभी ऐसा नहीं होता है जैसा हम चाहते हैं।

पारंपरिक दृश्य का लाभ यह है कि आप इसे अनुक्रमित दृश्य बना सकते हैं, और SQL सर्वर को अन्य प्रदर्शन सहायता प्रदान कर सकते हैं; हालांकि, आपको बस परीक्षण करना और देखना होगा।

+0

पारंपरिक विचार इस क्लाइंट पर काम नहीं करेंगे क्योंकि डीबीए डीबी में गैर-विक्रेता-परिभाषित वस्तुओं को भी प्रतिरोधी रखने के लिए प्रतिरोधी है। नतीजतन, अधिकांश प्रश्न प्रत्येक रिपोर्ट में एम्बेड किए गए हैं (हम सीआर का उपयोग कर रहे हैं)। यूडीएफ के बारे में मैंने जो कारण सोचा था वह उनकी मॉड्यूलरिटी है। कठिन हिस्सा विचार पर डीबीए बेच रहा है ... क्या ओरेकल के भौतिक दृश्य के समान अनुक्रमित दृश्य है? – craig

+0

मैंने ओरेकल के साथ लंबे समय तक काम नहीं किया है, इसलिए मुझे नहीं पता। हालांकि, मैं इंगित करता हूं कि एक यूडीएफ एक गैर-विक्रेता-परिभाषित वस्तु है, इसलिए आप वहां एक ही पुशबैक में भाग सकते हैं। मेरा मानना ​​है कि एक अस्थायी तालिका या चर के साथ धारक का जवाब आपकी सबसे अच्छी शर्त हो सकता है यदि आप वस्तुओं को संशोधित करने के लिए सीमित हैं। बस एक तरफ के रूप में, मैं विक्रेता डीबीएस से निपटने के दौरान, क्रॉस-लिंक्ड टेबल, आदि के साथ एक माध्यमिक डीबी बनाने के लिए जाते हैं। इस तरह से मैं अपने डेटाबेस के बाहर कस्टम कोड हो सकता है; आप भविष्य में एक विकल्प के रूप में खोजना चाह सकते हैं। –

+2

इंडेक्स किए गए विचार ओरेकल भौतिक दृश्य के समान हैं। दृश्य को कुछ प्रतिबंधों के अनुरूप होना चाहिए: http://msdn.microsoft.com/en-us/library/ms191432.aspx और केवल एंटरप्राइज़ संस्करण डेटा पहुंच के लिए अनुक्रमित दृश्य का उपयोग करने पर विचार करेगा। मानक संस्करण और निचले संस्करणों को स्पष्ट रूप से iEXexED दृश्य के उपयोग को मजबूती से लागू करना चाहिए, http://msdn.microsoft.com/en-us/library/ms181151.aspx –

1

एसक्यूएल सर्वर 2005 उत्तर: आप temp/var तालिकाओं का उपयोग करके इनलाइन व्यू को कम कर सकते हैं। इन पर प्रदर्शन समस्याएं अस्थायी प्रविष्टियां हैं जिन्हें आपको क्वेरी पर प्रति हिट की आवश्यकता होती है, लेकिन यदि परिणाम सेट पर्याप्त छोटे होते हैं, तो वे मदद कर सकते हैं। आप चर सारणी पर प्राथमिक कुंजी, और प्राथमिक कुंजी/इंडेक्स पर टेम्पलेट टेबल पर उपयोग कर सकते हैं। सामान्य विश्वास के अलावा, मुझे कुछ लेख मिलते हैं जो इंगित करते हैं कि temp/var टेबल दोनों temp db में संग्रहीत हैं।

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

तो, सामान्य रूप से। हम यूडीएफ का उपयोग करते हैं, लेकिन जब हमें लगता है कि प्रदर्शन खराब हो गया है, तो हम क्वेरी को यूडीएफ चयनों को temp/var तालिकाओं में डालने और उन पर शामिल होने के लिए स्थानांतरित करते हैं।

उपयोग/रखरखाव की आसानी के लिए कार्यक्षमता बनाएं, और जहां और जब आवश्यक हो, प्रदर्शन प्रदर्शन लागू करें।

संपादित करें:

आप क्रिस्टल के लिए इस चलाया जा सकता है, और आप, संग्रहित प्रक्रियाओं का उपयोग हाँ, आप अस्थायी/var तालिकाओं के लिए अंदर सपा एसक्यूएल बयान निष्पादित कर सकते हैं की योजना है।

मुझे बताएं कि क्या आप एसपी का उपयोग करने जा रहे हैं। एसक्यूएल तब दिए गए पैरा के साथ एसपी योजनाओं को भी कैश करेगा।

क्रिस्टल के साथ पिछले प्रयोग से, चीजों से बचने के लिए, क्रिस्टल में समूहित किया जा रहा है जो एसपी में किया जा सकता है, यदि आवश्यक हो तो पृष्ठ संख्याएं। और फ़ंक्शन कॉल, अगर इसे सर्वर पर संभाला जा सकता है।

+0

मेरी अज्ञानता क्षमा करें, लेकिन क्या मैं मानक SQL कथन में एक temp/var तालिका का उपयोग कर सकता हूं? इसे एक रिपोर्टिंग टूल (क्रिस्टल रिपोर्ट्स) के भीतर से चलाने की आवश्यकता है। मुझे लगता है कि आपके समाधान के लिए एक एसपी की आवश्यकता है, है ना? यदि नहीं, तो क्या आप इस दृष्टिकोण पर थोड़ा और विस्तार कर सकते हैं? हम SQL सर्वर 2005 का उपयोग कर रहे हैं। – craig

+0

तालिका वर्र्स को डीबी के खिलाफ निष्पादित एसक्यूएल में जोड़ा जा सकता है। क्या आप ऐप से, या क्रिस्टल में एसक्यूएल का उपयोग कर रहे हैं? –

+0

क्रिस्टल रिपोर्ट्स 'कमांड ऑब्जेक्ट के भीतर - अनिवार्य रूप से कच्चे-एसक्यूएल कथन। मैंने देखा है कि डेटाबेस ड्राइव (यानी ओडीबीसी या ओएलडीडीबी) का एसक्यूएल की कार्यक्षमता पर असर पड़ता है। उदाहरण के लिए, मुझे अतीत में ओएलईडीबी के साथ दिए गए कथन का उपयोग करने में समस्याएं थीं, लेकिन ओडीबीसी के साथ नहीं। इससे अधिक उन्नत तकनीकों का उपयोग करने की मेरी क्षमता प्रभावित हो सकती है। – craig

8

एक सही ढंग से परिभाषित टीवीएफ कोई समस्या नहीं पेश करेगा। विचारों या अस्थायी तालिकाओं और चर के मुकाबले प्रदर्शन समस्याओं के लिए आपको इंटर्न वाले विस्फोटक टीवीएफ पर कई दावों का पता चल जाएगा। आम तौर पर समझ में नहीं आता है कि एक टीवीएफ एक दृश्य से अलग व्यवहार करता है। एक व्यू परिभाषा मूल क्वेरी में रखी जाती है और उसके बाद ऑप्टिमाइज़र क्वेरी ट्री को पुनर्व्यवस्थित करता है क्योंकि यह फिट दिखाई देता है (जब तक कि NOEXPAND क्लॉज अनुक्रमित दृश्यों पर उपयोग नहीं किया जाता है)। एक टीवीएफ में अलग-अलग अर्थशास्त्र होते हैं और कभी-कभी, विशेष रूप से डेटा अपडेट करते समय, परिणामस्वरूप टीवीएफ आउटपुट haloween protection के लिए स्पूल किया जाता है। यह WITH SCHEMABINDING फ़ंक्शन को चिह्नित करने में सहायता करता है, Improving query plans with the SCHEMABINDING option on T-SQL UDFs देखें।

निर्धारक और सटीक कार्य की अवधारणाओं को समझने के लिए भी महत्वपूर्ण है। हालांकि वे ज्यादातर स्केलर वैल्यू फनसीटन्स पर लागू होते हैं, टीवीएफ भी प्रभावित हो सकते हैं। User-Defined Function Design Guidelines देखें।

+0

वाह, कुछ सूक्ष्म बारीकियों। आपकी अंतर्दृष्टि के लिए धन्यवाद। – craig

+1

मेरा मानना ​​है कि एक टीवीएफ, यदि यह इनलाइन/बहुस्तरीय नहीं है, तो ऑप्टिमाइज़र द्वारा भी इसका विस्तार किया जाता है। दृश्य को बताते हुए विस्तारित किया गया है, लेकिन टीवीएफ के लिए इसका उल्लेख नहीं करना कुछ भ्रामक प्रतीत होता है। शायद इस जवाब को उल्लेख करने के लिए अद्यतन करें। हालांकि मैं इस पर कोई विशेषज्ञ नहीं हूँ। – AaronLS

2

चूंकि आपको SQL स्ट्रिंग की आवश्यकता है और सिस्टम में दृश्य या यूडीएफ जोड़ने की क्षमता नहीं हो सकती है, तो आप इसके साथ उपयोग करना चाहेंगे ... जटिल क्वेरी को एक स्थान पर सीमित करने के लिए (कम से कम इस कथन के लिए ।)।

WITH complex(patientid, datetime, measure_id, value) AS 
(Select... Complex Query) 
SELECT patient_id 
,  datetime 
,  m1.value AS physician_name 
,  m2.value AS blood_type 
,  m3.value AS rh 
FROM patient_table 
INNER JOIN (Select ,,,, From complex WHERE measure_id=1) m1... 
INNER JOIN (Select ,,,, From complex WHERE measure_id=2) m2... 
LEFT OUTER JOIN (Select ,,,, From complex WHERE measure_id=3) m3... 
+0

मानते हैं कि 'जटिल क्वेरी' WHERE क्लॉज के बिना 1,000,000 पंक्तियां लौटाती है (यह नहीं है, लेकिन यह मेरे प्रश्न को स्पष्ट करने में मदद करती है)। क्या डीबी एक बार 1,000,000 पंक्तियां उत्पन्न करेगा, प्रत्येक से जुड़ने के लिए इसका चयन करें (मेरे उदाहरण में तीन)। या यह इस से अनुकूलन का बेहतर काम करता है? मुझे नहीं लगता कि मैं इंडेक्स संकेत जोड़ सकता हूं? मुझे पता है कि अंतर्निहित तालिकाओं को अच्छी तरह अनुक्रमित नहीं किया गया है और हमारा डीबी कोई गैर-विक्रेता-परिभाषित इंडस्ट्रीज नहीं जोड़ देगा। – craig

+0

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

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