2010-07-13 7 views
13

fairamountofresearch और कुछ errors के बाद, मैंने अपना कोड संशोधित किया ताकि यह प्रत्येक बार डेटाबेस पूछताछ या डेटा डालने पर एक नया डेटा कॉन्टेक्स्ट बनाता है। और डेटाबेस अक्सर पूछताछ की जाती है - 250k लेनदेन के प्रत्येक प्रक्रिया के लिए, लेनदेन डालने से पहले डेटाबेस आईडी, डिपार्टमेंट आईडी और श्रेणी प्राप्त करने के लिए डेटाबेस से पूछताछ की जाती है।डेटाकॉन्टेक्स्ट का पुन: उपयोग करने का नकारात्मक प्रदर्शन प्रभाव क्यों होगा?

तो अब मैं कोड को अनुकूलित करने की कोशिश कर रहा हूं क्योंकि यह केवल 15 लेनदेन को एक सेकंड में संसाधित कर रहा था। मैंने कुछ अपर्याप्त प्रश्न हटा दिए और कुछ इंडेक्स जोड़े और इसे 30/सेक तक पहुंचा दिया। मैंने तब सोचा कि भले ही हर कोई डेटाकॉन्टेक्स्ट हल्का वजन रखता है, फिर भी लेनदेन प्रति नया 4 बार बनाने के लिए कुछ खर्च करना पड़ता है, इसलिए मैंने डेटाकॉन्टेक्स्ट का पुन: उपयोग करने का प्रयास किया। मैंने पाया, मेरे आश्चर्य की बात है कि, संदर्भ का पुन: उपयोग करने से प्रदर्शन को 10 लेनदेन में गिरावट आई है!

ऐसा क्यों होगा? क्या ऐसा इसलिए है क्योंकि DataContext स्मृति में इकाइयों को कैश करता है और डेटाबेस से पूछने से पहले इसकी इन-मेमोरी सूची के माध्यम से पहली बार खोज करता है? इसलिए, यदि, उदाहरण के लिए, मैं ग्राहक के लिए ग्राहक आईडी (प्राथमिक कुंजी) की तलाश कर रहा हूं, जिसका नाम 'एमसीएस' है और ग्राहक नाम कॉलम पर क्लस्टर इंडेक्स है ताकि डेटाबेस क्वेरी तेज हो, इन-मेमोरी लुकअप धीमा हो जाएगा?

और क्या यह सच है कि इतने सारे डीबी कनेक्शन बनाने/निपटाने से चीज़ें धीमा हो सकती हैं, या यह सिर्फ एक और समयपूर्व अनुकूलन है? और यदि यह सत्य है, तो डेटाकॉन्टेक्स्ट का पुन: उपयोग करने का कोई तरीका है लेकिन क्या यह प्रत्येक linq-to-sql क्वेरी के लिए एक वास्तविक डेटाबेस क्वेरी करता है?

उत्तर

12

यहाँ क्यों फिर से उपयोग कर एक DataContext एक सबसे अच्छा अभ्यास नहीं है, MSDN DataContext documentation से:

DataContext सभी संस्थाओं एक डेटाबेस कनेक्शन पर मैप किया गया का स्रोत है। यह परिवर्तन है कि आप सभी पुनः प्राप्त संस्थाओं के लिए बनाया गया है और एक "पहचान कैश" कि गारंटी देता है कि संस्थाओं को लिया गया एक से अधिक समय का प्रतिनिधित्व कर रहे एक ही वस्तु उदाहरण का उपयोग कर रखता है ट्रैक करता है।

सामान्य तौर पर, एक DataContext उदाहरण एक " काम की इकाई" के लिए पिछले करने के लिए बनाया है, लेकिन अपने आवेदन है कि इस शब्द को परिभाषित करता है। डेटाकॉन्टेक्स्ट हल्का वजन है और बनाने के लिए महंगा नहीं है। एक विशिष्ट LINQ से SQL एप्लिकेशन विधि स्कोप पर डेटाकॉन्टेक्स्ट उदाहरण बनाता है या अल्पकालिक वर्गों के सदस्य संबंधित डेटाबेस संचालन के लॉजिकल सेट का प्रतिनिधित्व करता है।

  1. DataContext के इन-स्मृति पहचान कैश इतना बड़ा हो जाता है, तो:

आप कर रहे प्रश्नों की एक बड़ी संख्या के लिए एक DataContext फिर से है, तो आपका प्रदर्शन संभावित कारणों की एक जोड़ी के लिए नीचा होगा कि इसे पेजफाइल पर लिखना शुरू करना है, तो आपका प्रदर्शन एचडी की रीड-हेड गति से बाध्य होगा और प्रभावी रूप से कैश का उपयोग करने का कोई कारण नहीं होगा।

  • स्मृति में अधिक पहचान वस्तुएं हैं, जितनी अधिक प्रत्येक बचत ऑपरेशन होती है।

  • अनिवार्य रूप से आप जो कर रहे हैं वह डेटाकॉन्टेक्स्ट क्लास के लिए यूओडब्ल्यू सिद्धांत का उल्लंघन कर रहा है।

    खुले डेटाबेस कनेक्शन के साथ कुछ ओवरहेड जुड़ा हुआ है, लेकिन लंबे समय तक कनेक्शन को खोलना (जो अक्सर एक टेबल लॉक करना भी होता है) उन्हें खोलने और बंद करने से कम बेहतर होता है।

    एक और कड़ी है जो या MSDN से तुम्हारी मदद नहीं कर सकते हैं हो सकता है:

    How to: Reuse a Connection Between an ADO.NET Command and a DataContext (LINQ to SQL)

    1

    यहां तक ​​कि क्लस्टर्ड इंडेक्स के साथ, इन-मेमोरी लुकअप हमेशा डाटाबेस क्वेरी से तेज़ होगा - किनारे के मामलों को छोड़कर, 386 बनाम एक क्रे - जैसे कि आप नेटवर्क से संबंधित देरी को कारक करते हैं।

    मुझे लगता है कि डेटाकॉन्टेक्स्ट की इकाइयों की हैंडलिंग के साथ गिरावट का अनुमान लगाया जाना चाहिए: एक संदर्भ का पुन: उपयोग करना लगातार ट्रैक की गई इकाइयों की संख्या में वृद्धि करेगा, और SaveChanges पर कॉल अधिक समय की आवश्यकता हो सकती है।

    फिर, यह अनुमान है - लेकिन यह वह जगह है जहां मैं दिखना शुरू कर दूंगा।

    1

    आप सब कुछ खत्म हो-टू-एंड और देखो जहां अपना समय वास्तव में खर्च किया जा रहा है प्रोफ़ाइल करना होगा।

    एक पंक्तिबद्ध होने पर एक क्लस्टर सूचकांक सबसे तेज़ नहीं है। सबसे तेज़ शायद एक कवर गैर-क्लस्टर सूचकांक होगा, लेकिन यह वास्तव में बिंदु के बगल में है।

    मुझे उम्मीद है कि अधिक प्रदर्शन प्राप्त करने के लिए, यदि आप वास्तव में क्षमताओं का उपयोग नहीं कर रहे हैं, तो शायद आपको कुछ ढांचे को झटके करना होगा। यदि आप क्षमताओं का उपयोग कर रहे हैं - ठीक है, तो आप यही भुगतान कर रहे हैं ...

    1

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

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

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