EF 4.1 में संस्थाओं को डालना क्यों ObjectContext की तुलना में इतना धीमा है?


81

मूल रूप से, मैं एक लेनदेन में 35000 ऑब्जेक्ट सम्मिलित करता हूं:

using(var uow = new MyContext()){
  for(int i = 1; i < 35000; i++) {
     var o = new MyObject()...;
     uow.MySet.Add(o);
  }
  uow.SaveChanges();
}

यह हमेशा के लिए लेता है! अगर मैं अंतर्निहित ObjectContext का उपयोग करता हूं (उपयोग करके IObjectAdapter), यह अभी भी धीमा है, लेकिन लगभग 20s का है। ऐसा लगता है कि DbSet<>कुछ रैखिक खोज कर रहा है, जिसमें समय की वर्ग राशि लगती है ...

इस समस्या को देखकर किसी और को?


3
मैं किसी भी तरह से मानता हूं कि इसका उत्तर इसके समान होगा: stackoverflow.com/questions/5917478/…
लादिस्लाव मृका

जवाबों:


128

जैसा कि टिप्पणी में पहले से ही लादिस्लाव ने संकेत दिया है, आपको प्रदर्शन में सुधार करने के लिए स्वचालित परिवर्तन का पता लगाने को अक्षम करना होगा:

context.Configuration.AutoDetectChangesEnabled = false;

यह परिवर्तन पहचान DbContextएपीआई में डिफ़ॉल्ट रूप से सक्षम है ।

एपीआई DbContextसे अलग व्यवहार करने का कारण यह ObjectContextहै कि स्वचालित परिवर्तन का पता लगने पर एपीआई के कार्यों की तुलना में DbContextएपीआई के कई और कार्य DetectChangesआंतरिक रूप से कॉल करेंगे ObjectContext

यहां आप उन फ़ंक्शन की सूची पा सकते हैं, जो DetectChangesडिफ़ॉल्ट रूप से कॉल करते हैं । वो हैं:

  • Add, Attach, Find, Local, या Removeपर सदस्योंDbSet
  • GetValidationErrors, Entry, या SaveChangesपर सदस्योंDbContext
  • Entriesपर विधिDbChangeTracker

विशेष रूप से Addकॉल DetectChangesजो आपके खराब प्रदर्शन के लिए जिम्मेदार है।

मैं इसके विपरीत ObjectContextएपीआई DetectChangesकेवल स्वचालित रूप से कॉल करता हूं , SaveChangesलेकिन अंदर नहीं है AddObjectऔर उपरोक्त वर्णित अन्य संगत तरीके। यही कारण है कि डिफ़ॉल्ट प्रदर्शन ObjectContextतेज है।

उन्होंने DbContextइतने सारे कार्यों में इस डिफ़ॉल्ट स्वत: परिवर्तन का परिचय क्यों दिया ? मुझे यकीन नहीं है, लेकिन ऐसा लगता है कि इसे अक्षम करना और DetectChangesउचित बिंदुओं पर मैन्युअल रूप से कॉल करना उन्नत माना जाता है और आसानी से आपके आवेदन में सूक्ष्म कीड़े को पेश कर सकता है इसलिए देखभाल के साथ [इसे] का उपयोग करें


@ लादिस्लाव: आप सही हैं मुझे यह नहीं मिला क्योंकि मैं केवल डालने की समस्याओं की खोज कर रहा था :-(
हार्टमुट

स्पष्टीकरण के लिए धन्यवाद। मैं वास्तव में संदर्भ बुला रहा था। Configuration.AutoDetectChangesEnabled = false लेकिन मैंने इसे बीज () विधि में डेटाबेस निर्माण के दौरान किया था। मुझे लगा कि यह डिफ़ॉल्ट सेट करेगा। मुझे पता नहीं था कि मुझे इसे प्रत्येक उदाहरण के लिए कॉल करना होगा। धन्यवाद!
हार्टमुट

3
@ हर्टमट: आप अपने व्युत्पन्न DbContext के कंस्ट्रक्टर के अंदर परिवर्तन का पता लगाने को अक्षम कर सकते हैं, फिर आपने हमेशा अक्षम किया है। लेकिन व्यक्तिगत रूप से यह टिप्पणी "संभावित रूप से सूक्ष्म कीड़े को पेश करने के बारे में" जब यह अक्षम होता है तो मुझे परेशान करता है। मैंने डिफ़ॉल्ट रूप से परिवर्तन का पता लगाया है और इसे केवल आपके जैसे कोड ब्लॉक में अक्षम कर दिया है, जहां प्रदर्शन में वृद्धि स्पष्ट है और जहां मुझे लगता है कि यह समस्या पैदा नहीं करता है।
सुलामा

मैं सहमत हूं, मैं केवल अपने आवेदन के कुछ प्रदर्शन महत्वपूर्ण हिस्से का परीक्षण कर रहा था। उत्पादन कोड में इसे थोक आवेषण आदि जैसे मामलों तक सीमित करना सबसे अच्छा है
हार्टमुट

इस उत्तर के लिए धन्यवाद। वहाँ जानकारी के बहुत सारे, लेकिन यह पीछा करने के लिए कटौती!
फ्रेड विल्सन

12

EF 4.3 CodeFirst के साथ थोड़ा अनुभवजन्य परीक्षण:

AutoDetectChanges = true: 23 sec के साथ 1000 ऑब्जेक्ट निकाले गए

AutoDetectChanges = false: 11 sec के साथ 1000 ऑब्जेक्ट निकाले गए

AutoDetectChanges = true: 21 sec के साथ 1000 ऑब्जेक्ट सम्मिलित किए गए

AutoDetectChanges = false: 13 sec के साथ 1000 ऑब्जेक्ट सम्मिलित किए गए


1
धन्यवाद Zax। प्रश्न के अनुसार 35,000 के साथ आपके परिणाम क्या हैं? आप देखेंगे कि मूल प्रश्न में यह tsates है कि प्रदर्शन चतुष्कोणीय रूप से गिरता है
Daniel Dyson


1

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

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

बस पता है कि सामान्य रूप से अपडेट की तुलना में अधिक समय लगेगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.