2011-08-08 10 views
13

हमारी कंपनी एक नया आवेदन है, जो अपने मूल में कुछ हद तक एक बड़े व्यावसायिक डेटा वस्तु है विकसित कर रहा है के साथ कोड-पहले इस्तेमाल करते हैं। हम बाहर इकाई की रूपरेखा आवेदन से डेटाबेस सार करने के लिए पहले कोड के साथ की कोशिश करने का फैसला किया, लेकिन चीजें धराशायी हो गए हैं। व्यापार वस्तु लगभग 60 वर्गों से बना है, और कुल 600 गुणों में से है; हालांकि, यह एक वृक्ष संरचना है और कोई क्रॉसओवर/बैकट्रैकिंग पॉइंटर्स मौजूद नहीं हैं।बेहद धीमी गति से प्रदर्शन इकाई की रूपरेखा 4.1 रिलीज

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

कुछ अधिक डेटा बिंदु: व्यापार वस्तु की जड़ के तहत प्रथम स्तर में 27 तत्वों रहे हैं। 3 तत्व मौजूद हैं (बाकी ने टिप्पणी की है), जोड़ने का समय 4.5 सेकंड है। 5 तत्व मौजूद हैं, यह 11.8 सेकंड है। 8 तत्व मौजूद हैं, यह 1 मिनट 12.5 सेकेंड है। जाहिर है, इन तत्वों का आकार महत्वपूर्ण रूप से भिन्न होता है, लेकिन ऐसा लगता है कि कुछ प्रकार की व्यवस्थित समस्या का संकेत मिलता है।

+3

क्या आपने एसक्यूएल प्रोफाइलर में एसक्यूएल को देखा है? कभी-कभी एसक्यूएल को देखकर ईएफ क्या करने की कोशिश कर रहा है, इस बारे में बहुत कुछ पता लगाया जा सकता है। मेरी राय में, डीबी में 60 संबंधित वर्गों को सहेजना ईएफ के लिए एक उप-दूसरे ऑपरेशन होना चाहिए। – automagic

+0

हमने यह कोशिश नहीं की थी, क्योंकि हम जानते थे कि यह अंत में डेटाबेस को मार रहा था और सभी प्रोसेसिंग ईएफ के अंदर हो रही थी। ट्रेस बहुत बड़ा है ... मुझे पूरा यकीन नहीं है कि मुझे क्या देखना चाहिए। – dythim

+1

'dbContext.Configuration.AutoDetectChangesEnabled = false;' सेट करने का प्रयास करें, जब आप संदर्भ बनाते हैं और फिर मापते हैं। चूंकि आप कहते हैं कि 'ऐड' धीमा है (और 'सेव चेंज' नहीं है, है ना?) मुझे संदेह है कि स्वचालित परिवर्तन पहचान/स्नैपशॉट निर्माण चीजों को धीमा कर देता है। – Slauma

उत्तर

3

तो, समस्या का पता लगाया। NHibernate के साथ आगे बढ़ते समय, हम एक संरचनात्मक त्रुटि में आए जो कुछ प्रयोगात्मक कोड था। यह श्रेणी अपने बच्चों की संपत्ति परिवर्तनित घटनाओं की सदस्यता ले रही थी, जिसके कारण एनएचबीरनेट को दुर्घटनाग्रस्त हो गया।

जो अच्छा है! उसने हमें बताया कि वास्तव में एक समस्या थी। इकाई फ्रेमवर्क किसी भी संकेत के बिना हमेशा के लिए भाग गया कि यह एक समस्या थी जिसके बारे में हम कुछ कर सकते थे।

तो वैसे भी, हम समय के लिए एनएचबीरनेट का उपयोग जारी रखने जा रहे हैं। हमें उस डेटाबेस संरचना पर नियंत्रण है जो हम इसका उपयोग करके प्राप्त करते हैं।

4

... हमारा परीक्षण डेटाबेस में कक्षा का एकल, अनियमित उदाहरण जोड़ना था। DbContext.Add ...

आप सुनिश्चित करें कि आपके कोड-सबसे पहले मॉडल इससे पहले कि आप Add बुलाया गया है बनाया है और स्मृति में लोड किया जाता किया था ले रहे हैं? मैं निम्नलिखित मतलब है: आप इस तरह एक परीक्षण कोड का उपयोग करते हैं ...

using (var context = new MyContext()) 
{ 
    var myHugeBusinessObject = CreateItSomeHow(); 

    context.HugeBusinessObjects.Add(myHugeBusinessObject); 

    context.SaveChanges(); 
} 

... और यह पहली बार है कि आप कुछ समय के लिए अपने परीक्षण आवेदन Add में संदर्भ का उपयोग कर रहे निर्माण करने के लिए वास्तव में खर्च किया जाएगा संदर्भ में वस्तु को जोड़ने से पहले स्मृति में ईएफ मॉडल।

आप Add कॉल करने से पहले इन दो चरणों अलग कर सकते हैं बस एक डमी विधि जोड़कर, जैसे उदाहरण के लिए कुछ: यह मैं बनाया के साथ

public class MyClass 
{ 
    public int Id { get; set; } 
    public string P1 { get; set; } 
    // ... P2 to P49 
    public string P50 { get; set; } 
    public MyClass Child1 { get; set; } 
    // ... Child1 to Child26 
    public MyClass Child27 { get; set; } 
} 

:

context.HugeBusinessObjects.Count(); 

मैं एक परीक्षण का निर्माण किया है एक वस्तु:

var my = new MyClass(); 
MyClass child = my; 
for (int i = 0; i < 100; i++) 
{ 
    child.Child1 = new MyClass(); 
    child = child.Child1; 
} 
child = my; 
for (int i = 0; i < 100; i++) 
{ 
    child.Child2 = new MyClass(); 
    child = child.Child2; 
} 
// and so on up to Child27 

तो इस ऑब्जेक्ट ग्राफ़ में 2700 बाल वस्तुएं बुद्धि हैं एच 50 स्केलर गुण प्रत्येक।

using (var context = new MyContext()) 
{ 
    var my = CreateWithTheCodeAbove(); 

    context.MyClassSet.Count(); 
    context.MyClassSet.Add(my); 

    context.SaveChanges(); 
} 

...Count() (= एफई मॉडल के निर्माण) मोटे तौर पर 25 सेकंड की जरूरत है: तो फिर मैं इस कोड का परीक्षण किया। Add जरूरतों 1 सेकंड। (ऊपर छोरों में 1000 के लिए 100 में परिवर्तन करना (ग्राफ में तो 27000 वस्तुओं वाले) 9-10 सेकंड के लिए लगभग रैखिक Add के लिए समय बढ़ जाती है।) इस परिणाम true या false को AutoDetectChangesEnabled की स्थापना से स्वतंत्र है।)

अगले दिलचस्प परिणाम: यदि मैं समय मॉडल (Count() उदाहरण कोड में निर्माण के साथ बिताए) 140 सेकंड को विस्फोट MyClass को 20 नेविगेशन गुण अधिक (Child47-Child28) जोड़ें। Add की अवधि केवल अतिरिक्त गुणों के साथ रैखिक रूप से बढ़ जाती है।

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

ऊपर दिए गए सुझावों के साथ इन चरणों का परीक्षण कुछ डमी कॉल के साथ अलग करने के लिए। यदि आपके पास पहले से ही यह अलगाव है ... ओम, इस पोस्ट को भूल जाओ।

+0

आपके सुझाव ने वास्तव में प्रदर्शन में काफी सुधार किया है! आवश्यक समय हमारे अन्य डेवलपर मशीनों में से एक को 5 मिनट से नीचे चला गया (मेरे कंप्यूटर का समय 8 मिनट था, जैसा कि मेरी शुरुआती पोस्ट में) 2.5 मिनट तक था, जो कि एक बड़ा अंतर है! दुर्भाग्यवश यह अभी भी उत्पादन तैयार नहीं है ... उस समय के लिए हम एनएचबर्ननेट को देखना शुरू कर रहे हैं, हालांकि अभी भी ईएफ को ध्यान में रखने की कोशिश कर रहे हैं। मैं समझता हूं कि आपने वास्तव में ईएफ के लिए आंतरिक संरचना शुरू करने से आने वाले अंतराल के बारे में क्या कहा था, लेकिन मुझे नहीं लगता कि इसे अलग क्यों करना चाहिए क्योंकि आपने कहा कि इतना बड़ा अंतर करना चाहिए। – dythim

+0

मैं अपने कोड का सरलीकृत मॉडल बनाने की कोशिश करूंगा जिसका प्रयोग परीक्षण के लिए किया जा सकता है (जैसा कि ऊपर वर्णित लाडिस्लाव)। – dythim

+0

@dythim: क्या आपका मतलब है कि * कुल * समय ('गणना() + जोड़ें()') केवल 'जोड़ें()' को कॉल करते समय आधा समय तक चला गया? यदि हां तो यह ऐसा कुछ है जिसे मैं उम्मीद नहीं करता। मैंने उम्मीद की थी कि समय वही है लेकिन असमान रूप से वितरित किया गया है: 'गणना() '(= मॉडल निर्माण)' जोड़ें()' से बहुत धीमी है। क्या आपने प्रत्येक कॉल का समय जांच लिया था और न केवल योग? आंतरिक मॉडल संरचना प्रति * एप्लिकेशन * उदाहरण के बाद ही बनाई जाती है। यदि मॉडल निर्माण प्रदर्शन समस्या है तो आपका प्रश्न दूसरे पर जाता है (मॉडल प्रारंभिक प्रदर्शन में सुधार कैसे करें)। – Slauma

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