2010-07-27 90 views
12

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

लेकिन जब मैंने प्रदर्शन तुलना की, तो ईएफ 4 बहुत धीमी थी। और मैं समझ नहीं पाया क्यों।

मैं निम्नलिखित संस्थाओं का उपयोग करें:

public class Recipe { private List _RecipePreparations; public int ID { get; set; } public String Name { get; set; } public String Description { get; set; } public List Tags { get; set; } public ICollection Preparations { get { return _RecipePreparations.AsReadOnly(); } }

public void AddPreparation(RecipePreparation preparation) 
    { 
     this._RecipePreparations.Add(preparation); 
    } 
} 

सार्वजनिक वर्ग RecipePreparation { सार्वजनिक स्ट्रिंग नाम {मिल; सेट; } सार्वजनिक स्ट्रिंग विवरण {प्राप्त करें; सेट; } सार्वजनिक int रेटिंग {प्राप्त करें; सेट; } सार्वजनिक सूची चरण {प्राप्त करें; सेट; } सार्वजनिक सूची टैग {प्राप्त करें; सेट; } सार्वजनिक int आईडी {प्राप्त करें; सेट; } }

प्रदर्शन मैं एक नुस्खा अप नयी परीक्षा में, और 50.000 RecipePrepations जोड़ें। तब मैं तो जैसे db4o में वस्तु संग्रहीत:

cookRecipes.Recipes.Add(recipe1); 
cookRecipes.SaveChanges(); 
:

IObjectContainer db = Db4oEmbedded.OpenFile(Db4oEmbedded.NewConfiguration(), @"RecipeDB.db4o"); 
db.Store(recipe1); 
db.Close(); 

यह चारों ओर 13.000 (ms)

मैं एसक्यूएल सर्वर 2008 में EF4 साथ सामान की दुकान (एक्सप्रेस, स्थानीय स्तर पर) इस तरह लेता है

और वह लेता है 200.000 (ms)

अब कैसे पृथ्वी पर db4o 15 (!!!) गुना तेजी से कि EF4/एसक्यूएल है? क्या मुझे ईएफ 4 के लिए एक गुप्त टर्बो बटन याद आ रहा है? मुझे यह भी लगता है कि डीबी 4o तेज हो सकता है? चूंकि मैं डेटाबेस फ़ाइल को प्रारंभ नहीं करता हूं, इसलिए मैं इसे गतिशील रूप से बढ़ने देता हूं।

+1

मेरा अनुमान है कि कई एकल डालने-बयानों की भूमि के ऊपर निष्पादित किया जा रहा अंतर का सबसे बड़ा हिस्सा है। क्या ओवरहेड को कम करने के लिए सम्मिलित बयान को गठबंधन करने के लिए ईएफ 4 को निर्देश देने का कोई तरीका है? –

+0

@Lasse: हाँ, वहाँ है। ईएफ बॉक्स के बाहर कार्य पैटर्न की इकाई लागू करता है - मेरा जवाब देखें। –

+1

मैंने विजुअल स्टूडियो के साथ कुछ प्रोफाइलिंग की है। और cookRecipes.Recipes.Add (रेसिपी 1) स्टोर करने के लिए कुल समय का लगभग 65% लेते हैं, और SaveChanges लगभग 35% (duh ...;))। – Saab

उत्तर

3

क्या आपने को लूप के अंदर कॉल किया था? कोई आश्चर्य नहीं कि यह धीमा है! ऐसा करने का प्रयास करें:

foreach(var recipe in The500000Recipes) 
{ 
    cookRecipes.Recipes.Add(recipe); 
} 
cookRecipes.SaveChanges(); 

एफई आप सभी अपने इच्छित परिवर्तन करें करने की उम्मीद है, और फिर एक बारSaveChangesकहते हैं। इस तरह, यह आपके द्वारा पूर्ववत किए गए सभी परिवर्तनों को अनदेखा कर, राज्य खोलने और राज्य को सहेजने के बीच परिवर्तन करने के लिए डेटाबेस संचार और एसक्यूएल अनुकूलित कर सकता है। (उदाहरण के लिए, 50 000 रिकॉर्ड जोड़कर, उनमें से आधे को हटाकर, SaveChanges को मारने से डेटाबेस में केवल 25 000 रिकॉर्ड जोड़े जाएंगे। कभी भी)

+0

डीओ 4o या ईएफ 4/एसक्यूएल में किसी भी डेटा को संग्रहीत करने से पहले लूप था। तो मैं पहली बार पकाने की विधि तैयार करता हूं, फिर एक लूप में मैं पकाने की विधि जोड़ता हूं। तो अब मेरे पास एक पकाने की विधि है, जिसमें 50,000 पकाने की विधि से जुड़ा हुआ है। मैं इसे डीबी 4o या ईएफ 4/एसक्यूएल में संग्रहीत करता हूं। तो डीबी 4o में एक डीबी.स्टोर (रेसिपी 1), और एक सिंगल कुक रेसिपीस। रेप्सिस। जोड़ें (रेसिपी 1); cookRecipes.SaveChanges() EF4 में। – Saab

+0

डीबी 4 ओ आपकी स्थानीय मशीन पर फ़ाइल में सहेज रहा है? और ईएफ 4 को स्थानीय रूप से डेटाबेस कनेक्शन खोलना है। कनेक्शन आम तौर पर खुला रहता है, इसलिए यह एक बार प्रति लॉन्च लागत है। समीकरण के कनेक्शन कनेक्शन को प्राप्त करने के लिए आवेषण के लिए अपने टाइमिंग लूप से पहले डेटाबेस में पहली आइटम प्राप्त करने के लिए एक पंक्ति जोड़ने का प्रयास करें। – DamienG

1

ईएफ कई चीजों में उत्कृष्टता प्राप्त करता है, लेकिन थोक लोडिंग उनमें से एक नहीं है । यदि आप उच्च-प्रदर्शन थोक लोडिंग चाहते हैं, तो इसे सीधे डीबी सर्वर के माध्यम से से ORM से तेज होगा। यदि आपके ऐप की एकमात्र प्रदर्शन बाधा थोक लोडिंग है, तो आपको शायद ईएफ का उपयोग नहीं करना चाहिए।

+0

फिर मुझे ईएफ के उपयोग के बारे में संदेह है। जब आप ऐप एक जटिल मॉडल (डोमेन ऑब्जेक्ट्स) पर निर्भर करते हैं तो मैं एक ओओ डेटाबेस (जैसे डीबी 4o) पसंद करूंगा। लेकिन जब डेटा मुख्य रूप से सारणीबद्ध होता है तो आप पारंपरिक संबंधपरक डेटाबेस का उपयोग करेंगे, और वैकल्पिक रूप से एक OR/M जैसे ईएफ। लेकिन जैसा कि आप कहते हैं कि ईएफ विफल रहता है जब आप भारी थोक भार/डालने/अपडेट करते हैं। तो मैं वास्तव में सच था कि क्या डर था। ईएफ 4 केवल एक विकल्प है जब बहुत हल्का डेटाबेस संचालन कर रहा है, और आप एक रिलेशनल डेटाबेस का उपयोग करने के लिए अटक गए हैं। – Saab

+1

फिर से, केवल ईएफ नहीं, लेकिन * कोई * ओआरएम डीबी सर्वर की थोक लोडिंग सुविधाओं की तुलना में धीमा हो जाएगा। ईएफ ओआरएम की तुलना में धीमा हो सकता है जो थोक आवेषण का समर्थन करता है, लेकिन यहां तक ​​कि वे डीबी सर्वर पर इस्तेमाल होने वाली स्ट्रीमिंग एपीआई के रूप में तेज़ी से नहीं होंगे, जो थोक लोडिंग सुविधाओं को समर्पित करते हैं। थोक लोडिंग अधिकांश ऐप्स के लिए एक कोने केस है, लेकिन यदि यह आपकी रोटी और मक्खन है तो आप ओआरएम की तुलना में एसएसआईएस की तरह कुछ उपयोग करने के लिए बेहतर करेंगे। –

+0

मैं मानता हूं कि अधिकतर OR/M की धीमी गति होगी कि केवल थोक लोडिंग। लेकिन मुझे इस बात से असहमत होना है कि एक OR/M डेटाबेस की थोक लोडिंग सुविधाओं का भी उपयोग नहीं कर सका। कोड उत्पन्न करना बहुत आसान है। लेकिन मुझे लगता है कि ईएफ 4 कोड पहले कुछ गलत हो रहा है। चूंकि पकाने की विधि को डीबीकॉन्टेक्स्ट में जोड़ना बहुत समय लगता है (130 सेकंड)। डेटाबेस में संग्रहीत (dbContext.Recipes.SaveChanges) 50.001 पंक्तियों के लिए 70 सेकंड या तो गति राक्षस नहीं है। जो 50.000/70 = 714 पंक्ति/एस में अनुवाद करता है। – Saab

1

बस अन्य उत्तरों पर जोड़ने के लिए: db4o आमतौर पर प्रक्रिया में चलता है, जबकि ईएफ एक आउट-ऑफ-प्रोसेस (एसक्यूएल) डेटाबेस को सारणीबद्ध करता है। हालांकि, डीबी 4o अनिवार्य रूप से सिंगल-थ्रेडेड है।इसलिए, एक अनुरोध के साथ यह एक उदाहरण के लिए तेज़ हो सकता है, एसक्यूएल एक डिफ़ॉल्ट डीबी 4o डेटाबेस सेटअप से अधिक बेहतर समेकन (एकाधिक प्रश्न, एकाधिक उपयोगकर्ता) को संभालेगा।

2

शायद आप नई ऑब्जेक्ट्स जोड़ने के दौरान चेंजट्रैकिंग को अक्षम कर सकते हैं, इससे वास्तव में प्रदर्शन में वृद्धि होगी।

context.Configuration.AutoDetectChangesEnabled = false; 

अधिक जानकारी के लिए यह भी देखें: http://coding.abel.nu/2012/03/ef-code-first-change-tracking/

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

  • कोई संबंधित समस्या नहीं^_^