ठीक है, मैं इस पर वजन नहीं ले रहा था, लेकिन डिएगो का जवाब पर्याप्त चीजों को जटिल करता है जो मुझे लगता है कि कुछ अतिरिक्त स्पष्टीकरण सुव्यवस्थित है।
ज्यादातर मामलों में, .Any()
तेज होगा। यहां कुछ उदाहरण दिए गए हैं।
Workflows.Where(w => w.Activities.Any())
Workflows.Where(w => w.Activities.Any(a => a.Title == "xyz"))
उपरोक्त दो उदाहरणों में, इकाई फ्रेमवर्क एक इष्टतम क्वेरी उत्पन्न करता है। .Any()
कॉल एक अनुमान का हिस्सा है, और इकाई फ्रेमवर्क इस अच्छी तरह से संभालता है। हालांकि, हम परिणाम इस तरह सेट की .Any()
भाग का परिणाम बनाने यदि:
Workflows.Select(w => w.Activities.Any(a => a.Title == "xyz"))
... अचानक इकाई की रूपरेखा हालत के दो संस्करण बनाने का निर्णय लेती है, तो क्वेरी के रूप में ज्यादा के रूप में दो बार यह काम करता है वास्तव में करने की जरूरत है।हालांकि, निम्न क्वेरी किसी भी बेहतर नहीं है:
Workflows.Select(w => w.Activities.Count(a => a.Title == "xyz") > 0)
ऊपर क्वेरी को देखते हुए, इकाई की रूपरेखा अभी भी हालत के दो संस्करणों का निर्माण करेगा प्लस यह भी एसक्यूएल सर्वर की आवश्यकता होगी एक वास्तविक गणना करने के लिए है, जो इसका मतलब है जैसे ही कोई आइटम पाता है, शॉर्ट-सर्किट में नहीं मिलता है।
लेकिन अगर आप इन दो प्रश्नों की तुलना कर रहे:
Activities.Any(a => a.Title == "xyz")
Activities.Count(a => a.Title == "xyz") > 0
... तेजी से हो जाएगा जो? निर्भर करता है।
पहली क्वेरी एक अक्षम डबल-कंडीशन क्वेरी उत्पन्न करती है, जिसका अर्थ है कि इसे दो गुना तक लेना होगा।
दूसरी क्वेरी डेटाबेस में प्रत्येक आइटम को शॉर्ट-सर्किटिंग के बिना जांचने के लिए मजबूर करती है, जिसका अर्थ है कि इसे N
गुना अधिक समय तक लेना पड़ सकता है, इस पर निर्भर करता है कि मैच खोजने से पहले कितने आइटमों का मूल्यांकन किया जाना चाहिए । की मेज मान लेते हैं 10,000 आइटम नहीं है:
- तालिका में कोई आइटम हालत मेल खाता है, इस प्रश्न के पहले प्रश्न के रूप में लगभग आधा समय ले जाएगा।
- यदि तालिका में पहला आइटम स्थिति से मेल खाता है, तो इस क्वेरी में पहली क्वेरी की तुलना में लगभग 5,000 गुना अधिक लगेगा।
- यदि तालिका में एक आइटम एक मैच है, तो यह क्वेरी पहली क्वेरी की तुलना में औसत 2,500 गुना अधिक ले जाएगी।
- यदि क्वेरी
Title
और कुंजी कॉलम पर एक सूचकांक का लाभ उठाने में सक्षम है, तो यह क्वेरी पहली क्वेरी के रूप में लगभग आधे समय ले जाएगी।
तो सारांश में
, यदि आप:
- का उपयोग
इकाई की रूपरेखा 4 (नए संस्करण क्वेरी संरचना में सुधार हो सकता के बाद से)
इकाई की रूपरेखा 6.1 या उससे पहले (6.1.1 has a fix to improve the query के बाद से), और
- तालिका के खिलाफ सीधे पूछताछ (जैसा कि उप-क्वेरी करने के विपरीत है), और
- परिणाम का उपयोग सीधे (जैसा कि भविष्यवाणी का हिस्सा है) का उपयोग करना, और
- ईट उसे:
- आप अच्छा अनुक्रमित तालिका आप जानना चाहते हैं पर स्थापित है, या
- आप आइटम समय के बहुमत पाया जा करने के लिए नहीं की उम्मीद
तो आप .Any()
उम्मीद कर सकते हैं .Count()
जितना अधिक समय तक लेना। उदाहरण के लिए, एक प्रश्न 50 के बजाय 100 मिलीसेकंड ले सकता है। या 5 के बजाय 10।
किसी भी अन्य परिस्थिति.Any()
में कम से कम तेजी से रूप होना चाहिए, और परिमाण के संभवतः आदेश तेजी से.Count()
से।
भले ही, जब तक कि आपने यह निर्धारित नहीं किया है कि यह वास्तव में आपके उत्पाद में खराब प्रदर्शन का स्रोत है, तो आपको समझना आसान है कि आपको क्या समझना आसान है। .Any()
अधिक स्पष्ट और संक्षिप्त रूप से बताता है कि आप वास्तव में क्या पता लगाने की कोशिश कर रहे हैं, इसलिए इसके साथ चिपके रहें।
+1। स्पष्टीकरण के लिए: पूरे मिलान सेट को गिनती डेटाबेस स्तर पर की जाती है, इसलिए यह आपके एप्लिकेशन में ऑब्जेक्ट्स नहीं ला रहा है। अभी भी 'कोई() 'सरल है, और यह' कहीं भी (x => x.Count> 0) 'से बेहतर प्रदर्शन करेगा, इसलिए इसे प्राथमिकता दी जानी चाहिए। – StriplingWarrior
@StriplingWarrior यह सच है कि गणना डीबी में की जाती है, लेकिन यह अभी भी गिनती से भी बदतर है, ईएफ की भयानक क्वेरी पीढ़ी के लिए धन्यवाद। मेरा जवाब देखें –