2012-04-04 10 views
5

किसी चयनित मुख्य श्रेणी की सभी बाल श्रेणियों में सभी उत्पादों को प्राप्त करने का सबसे अच्छा तरीका क्या होगा? लगभग 80 बाल श्रेणियों में 10000 उत्पाद प्राप्त करने का प्रयास कर रहा है लेकिन यह विधि बहुत धीमी है। कोई सुझाव? लिंक से एसक्यूएल सी # सभी बच्चे/उप-बच्चे में उत्पाद प्राप्त करें श्रेणियाँ बहुत धीमी

//list for the child categories 
private List<int> catsChildList = new List<int>(); 

GetChildCats(123); 

//get all the child categories of main category '123' 

private void GetChildCats(int _parentCat) 
{ 
    var cats = (from c in db2.tbl_cart_categories 
       where c.ParentID == _parentCat 
       select new { c.CategoryID }); 
    if (cats.Count() > 0) 
    { 
     foreach (var cat in cats) 
     { 
      int _cat = Convert.ToInt32(cat.CategoryID); 
      catsChildList.Add(_cat); 
      GetChildCats(_cat); 
     } 
    } 
} 

//Get the products 
var products = (from p in db2.products_infos 
      where p.IsEnabled == true 
      group p by p.ProdID 
      into g where g.Any(x => catsChildList.Contains(Convert.ToInt32(x.CategoryID))) 

SQL करने के लिए सी # और LINQ का उपयोग कर के बारे में 6 सेकंड लेता परिणाम

+1

क्या आपके पास उचित अनुक्रमणिका हैं? एसक्यूएल के लिए यह इकाई ढांचा या linq है? –

+0

क्या आपको श्रेणी आईडी को वर्चर से int में बदलने की अनुमति है? –

+0

हाँ इंडेक्स हैं। यह एसक्यूएल के लिए लिंक है। श्रेणी आईडी int है लेकिन शून्य स्वीकार करता है। मुख्य श्रेणियाँ पैरेंट आईडी शून्य थैंक्स – vts

उत्तर

3

var products = 
    (
    from p in db2.products_infos 
    where p.IsEnabled == true 
    group p by p.ProdID 
    into g where g.Any(x => catsChildList.Contains(Convert.ToInt32(x.CategoryID))) 
    select g 
    ); 

और

var tmpList = 
    (
    from p in db2.products_infos 
    where p.IsEnabled == true 
      && catsChildList.Contains(Convert.ToInt32(p.CategoryID))) 
    select p 
    ).ToList(); 

var products = 
    (from r in tmpList group p by r.ProdID into g select g); 

के बीच क्या अंतर है?

शायद मेरी स्कीमा अलग है, लेकिन जब मैं लिंक 2 एसक्यूएल के साथ कोशिश करता हूं तो यह एक ही परिणाम लौटाता प्रतीत होता है, लेकिन बाद वाले परिणाम एक डेटाबेस हिट में परिणाम लौटाते हैं, जबकि पूर्व कई अनुरोधों को जारी करते हैं। (यदि लौटाए गए उत्पादों की संख्या 10000 है, तो यह 10001 डेटाबेस अनुरोध कर रही होगी)।

+0

कमाल! यह बहुत अच्छा काम करता है। 1 सेकंड से भी कम समय में। धन्यवाद – vts

+0

यह क्यों है। टॉलिस्ट(); इसे तेजी से चलाता है लेकिन इसके बिना यह बहुत धीमा हो जाता है? – vts

+0

। टोलीस्ट() उस चरण में उत्पादों को पुनर्प्राप्त करने के लिए मजबूर करता है और यह एक फ्लायर है वाई सीधे आगे की क्वेरी। समूह को तब स्मृति में किया जाता है। .ToList() के बिना, आप Linq2SQL को समूह और चयन दोनों करने के लिए कह रहे हैं, और ऐसा लगता है कि यह एक अच्छा काम नहीं करता है। नोट, यदि आप सिर्फ प्रति श्रेणी (और उत्पादों के विवरण नहीं) उत्पादों की संख्या चाहते थे, तो। टोस्टिस्ट() चीजों को धीमा कर देगा क्योंकि इसका मतलब 10000 उत्पादों के विवरण को वापस करना होगा और फिर उन्हें समूहित करना और उनकी गणना करना होगा, जबकि बिना। टोस्टिस्ट(), यह एसक्यूएल को समूह से पूछने और उन्हें गिनने के लिए कहेंगे। – sgmoore

2

आँकड़े & कोड प्रदान के आधार पर लौटने के लिए, तो आप इस लाइन को हटाने के द्वारा 3 सेकंड बचाने चाहिए:

if (cats.Count() > 0) 

... क्योंकि यह गणनाओं को दोगुना करता है (और इसका मतलब है कि आप अपने डेटाबेस कॉल को दोगुना कर रहे हैं, यह खराब है) और बहुत अधिक व्यर्थ है क्योंकि उसके बाद कुछ भी नहीं है यदि गणना == 0.

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

+4

यदि उन्हें जांचने की आवश्यकता है, तो उन्हें 'बिल्लियों' किसी भी() 'का उपयोग करना चाहिए या इससे पहले कि' foreach' लूप भी नहीं होगा। – user7116

+0

मुझे लगता है कि 'किसी भी' के परिणामस्वरूप एक अतिरिक्त डेटाबेस भी मारा जाएगा लेकिन अच्छा बिंदु। –

+0

धन्यवाद। दुर्भाग्य से इससे ज्यादा मदद नहीं मिली। मेरा मानना ​​है कि यह मुद्दा g.Any (x => catsChildList.Contains (Convert.ToInt32 (x.CategoryID) के साथ है। सूची के विरुद्ध प्रत्येक उत्पाद को जांचने के लिए। – vts

0

ए। कोड की निम्न पंक्ति GetChildCats() विधि के माध्यम से पहली पंक्ति का लैम्ब्डा अभिव्यक्ति प्रतिस्थापन है।

var findCatList = (List<int> parent) => {   
    from c in db2.tbl_cart_categories 
      where & c.ParentID == _parentCat 
      select (db2.tbl_cart_categories.Any(cat=> cat.ParentID == c.CategoryID) ? 
       findCatList(c.CategoryID) 
       :new { c.CategoryID }      
       )} 

var catList = findCatList(123); 

लेकिन यह भी रिकर्सन करेगा, लेकिन आंतरिक रूप से किया जाएगा। कृपया इसे जांचें। बेशक यह एक अनचाहे कोड है, बस अपनी वस्तुओं के आधार पर।

बी। अन्य सोचते हैं कि आप कोशिश कर सकते हैं, आप db2.tbl_cart_categories को db2.tbl_cart_categories.AsParallel() में बदलने का प्रयास कर सकते हैं। मुझे इस बारे में निश्चित नहीं है कि ऑब्जेक्ट कॉन्टेक्स्ट/डेटा कॉन्टेक्स्ट इस के साथ कैसे व्यवहार करता है। लेकिन डीबी 2 एक संदर्भ वस्तु नहीं है तो मुझे यकीन है कि यह प्रदर्शन बेहतर होगा।

0

सबसे पहले, हालांकि आप निर्दिष्ट नहीं करते हैं, मुझे लगता है कि आप लिंक से एसक्यूएल का उपयोग कर रहे हैं। कृपया उस जानकारी को शामिल करने के लिए अपना प्रश्न अपडेट करें।

कुछ बुनियादी प्रोफाइलिंग जोड़कर प्रारंभ करें। कौन सी क्वेरी चलाने के लिए सबसे लंबा समय ले रही है?

g.Any(x => catsChildList.Contains(Convert.ToInt32(x.CategoryID))) 

यह निश्चित रूप से संदिग्ध है। यदि बिल्लियोंChildList के पास बहुत सारे मूल्य हैं, तो आप संभावित रूप से एक विशाल इन क्लॉज उत्पन्न कर सकते हैं, जो हमेशा धीरे-धीरे चलने वाला होता है। आप इसे चला रहे वास्तविक SQL कथन की जांच करके सत्यापित कर सकते हैं।

सच्चाई यह है कि इस तरह के रिकर्सिव पदानुक्रम ट्रैवर्सल कभी भी प्रभावी नहीं होंगे जब आप अपने आवेदन में हर पुनरावृत्ति करने की कोशिश कर रहे हैं। संग्रहीत प्रक्रिया का उपयोग करके आपको बेहतर प्रदर्शन मिलेगा।

+0

यह एसक्यूएल के लिए लिंग है। हाँ 80 बच्चे श्रेणियां हैं यह समझ में आता है कि यह समस्या है। स्टोर प्रक्रिया को चलाने वाले एसक्यूएल कथन की तुलना में कैसे दिखता है? क्या एसपी के साथ ऐसा करने का एक बेहतर तरीका है? धन्यवाद – vts

+0

एक संग्रहित प्रक्रिया बनाने के बाद आप इसे खींच सकते हैं आपके एंटिटी मॉडल आरेख में और यह सूची में दिखाई देगा (डिज़ाइन व्यू में नहीं)। वहां से आप सीधे एसपी को कॉल कर सकते हैं और एक एंटिटी वापस कर सकते हैं जो एसपी से आपके कॉलम आउटपुट को दोहराता है। –

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

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