2010-12-16 7 views
11

बस सोच रहा है, क्या इससे कोई फर्क पड़ता है कि LINQ विधियों को किस क्रम में जोड़ा गया है?किसी भी महत्व के LINQ विधि का अनुक्रम?

ईजी।

using(MyDataContext context = new MyDataContext()) 
{ 
    var user = context.Users 
        .Where(u => u.UserName.StartsWith("t")) 
        .OrderByDescending(u => u.CreatedDate) 
        .FirstOrDefault(); 
} 

और इस पूरी तरह से कर रहे हैं एक ही?

using(MyDataContext context = new MyDataContext()) 
{ 
    var user = context.Users 
        .OrderByDescending(u => u.CreatedDate) 
        .Where(u => u.UserName.StartsWith("t")) 
        .FirstOrDefault(); 
} 

बेशक, मैं सभी विधियों को एक-एक करके परीक्षण कर सकता हूं, लेकिन मैं तर्क के बारे में कुछ सामान्य विचार रखना चाहता हूं।

तो:

  • FirstOrDefault(), ToList() और अन्य तरीकों की तरह तरीकों कि वास्तव में निष्पादन को गति प्रदान करने के अलावा किसी भी महत्व के यह है LINQ बयान में आदेश के कुछ प्रकार के लिए?

धन्यवाद फिर से!

+0

ऐसे मामलों में मैं निष्पादन योजना का विश्लेषण करने के लिए मैन्युअल रूप से डेटाबेस पर निष्पादित और निष्पादित क्वेरी की तुलना करता हूं। –

उत्तर

10

LINQ से SQL में, मुझे उम्मीद है कि ये दो प्रश्न समान होंगे - कम से कम, एक ही क्वेरी योजना के साथ समाप्त होना चाहिए, भले ही सटीक समान SQL न हो।

LINQ से ऑब्जेक्ट्स में, वे बहुत अलग व्यवहार करेंगे। कल्पना कीजिए कि आपके पास दस लाख उपयोगकर्ता थे, लेकिन उनमें से केवल दो में "टी" से शुरू होने वाले उपयोगकर्ता नाम थे। पहले फॉर्म में, आप फ़िल्टरिंग करना शुरू कर देंगे और फिर उन दो उपयोगकर्ताओं को सॉर्ट कर देंगे ... दूसरे फॉर्म में, इसे फ़िल्टरिंग शुरू करने से पहले सब कुछ सॉर्ट करना होगा।

बेशक अन्य स्थितियां हैं जहां ऑर्डरिंग भी मायने रखती है - विशेष रूप से, यदि आपके पास Select आधा रास्ता नीचे है और फिर Where क्लॉज है, तो आप अलग-अलग चीज़ों पर फ़िल्टरिंग करेंगे। इस कल्पना कीजिए:

var query = Enumerable.Range(-20, 30) 
         .Select(x => -x) 
         .Where(x => x > 5); 

बनाम

var query = Enumerable.Range(-20, 30) 
         .Where(x => x > 5) 
         .Select(x => -x); 

पहले उदाहरण में परिणाम हो जाएगा "20, 19, 18, ... 6" जबकि दूसरे प्रश्न में परिणाम हो जाएगा "-6 , -7, -8, -9, -10 "। बहुत अलग!

1

मैं 100% निश्चित नहीं हूं लेकिन मुझे लगता है कि दूसरा धीमा है क्योंकि आप डेटा के बड़े सेट पर सॉर्टिंग करते हैं। यदि आप पहले फ़िल्टर करते हैं तो आप सॉर्टिंग को तेज़ी से बनाने वाले कुछ तत्वों को हटा देंगे। हालांकि, परिणाम वही होना चाहिए।

संपादित करें: चूंकि यह linq-to-sql (यदि आप किसी अन्य linq प्रदाता का उपयोग नहीं कर रहे हैं) की तरह दिखता है, तो इसे इस उदाहरण में निष्पादित उसी क्वेरी पर उबालना चाहिए। लेकिन ऐसी परिस्थितियां हैं जहां ऑर्डरिंग linq-to-sql में भी मायने रखती है (जॉन का उदाहरण देखें)। हालांकि, 100% सुनिश्चित करने का एकमात्र तरीका जेनरेट एसक्यूएल क्वेरी की जांच करने के लिए प्रोफाइलर का उपयोग करना है (लेकिन इस उदाहरण में मुझे नहीं लगता कि कोई अंतर है)।

+0

@ टॉमस: यह LINQ से SQL है, इसे देखकर ... मैं * या * क्लाइंट पर क्वेरी पीढ़ी * या * सर्वर-साइड ऑप्टिमाइज़र को स्पॉट करने की अपेक्षा करता हूं। –

+0

@ जोन: यह सच है, linq के लिए sql के लिए वे एक ही एसक्यूएल उत्पन्न करना चाहिए। मैंने केवल linq भाग को माना और 'DataContext' पर प्रतिबिंबित नहीं किया। इसके साथ बात यह है कि आप इसके बारे में निश्चित नहीं हो सकते हैं, या आप कर सकते हैं? जेनरेट एसक्यूएल क्वेरी का वास्तव में निरीक्षण करने के लिए प्रोफाइलर का उपयोग करने का एकमात्र तरीका है। –

+0

@ टॉमस: मैं इस मामले में उचित रूप से आत्मविश्वास रखूंगा - लेकिन मुझे लगता है कि यह देखना एक अच्छा विचार है कि आपका LINQ किस प्रकार के प्रश्नों का उत्पादन कर रहा है :) –

0

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

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

+0

@ Øyvind: अन्य उत्तरों पर मेरी टिप्पणियों के अनुसार: यह LINQ से SQL की तरह दिखता है, जहां निष्पादन प्रवाह लगभग निर्धारित नहीं है क्योंकि यह LINQ से ऑब्जेक्ट्स के लिए होगा। मैं उम्मीद करता हूं कि दोनों डेटा की विशाल मात्रा पर समान रूप से प्रदर्शन करें - क्योंकि SQL क्वेरी ऑप्टिमाइज़र को इसे सॉर्ट करना चाहिए। –

+0

@ जोन - प्रश्न की समीक्षा करते समय मैं आपसे सहमत हूं कि यह LINQ से SQL की तरह दिखता है, और फिर निश्चित रूप से आप सही हैं। हालांकि LINQ से ऑब्जेक्ट्स पर, अंतर महत्वपूर्ण होगा। –

1

सामान्य रूप से, हाँ इससे कोई फर्क नहीं पड़ता। आप अलग प्रदर्शन और/या विभिन्न परिणाम प्राप्त कर सकते हैं।

आपके विशिष्ट उदाहरण में ऑर्डर परिणाम नहीं बदलेगा। अधिकांश प्रदाताओं जैसे LINQ से SQL, और LINQ से Entities के लिए यह भी कोई फर्क नहीं पड़ेगा - वही SQL उत्पन्न होगा।

अन्य प्रदाताओं के लिए अलग-अलग ऑर्डर प्रदर्शन विशेषताओं को बदल सकता है, लेकिन यह विशिष्ट प्रदाता पर निर्भर करता है। उदाहरण के लिए मुझे नहीं लगता कि LINQ से ऑब्जेक्ट्स दोनों प्रश्नों के लिए समान प्रदर्शन करेंगे।

1

एसक्यूएल प्रोफाइलर का उपयोग करने के बारे में कैसे? वह सही जवाब देगा।

4

यह इस बात पर निर्भर करता है कि आप किस LINQ प्रदाता का उपयोग कर रहे हैं। LINQ से SQL के मामले में, अभिव्यक्ति वृक्ष किसी भी मामले में समान अंतर्निहित SQL क्वेरी को पार्स कर देगा। हालांकि, कम बुद्धिमान प्रदाता के साथ आप पाएंगे कि .Where() पहले करना अधिक कुशल होगा, क्योंकि यह उन्हें क्रमबद्ध करने से पहले आपके ऑब्जेक्ट्स को फ़िल्टर करेगा, जो बड़ी संख्या में इकाइयों के साथ काफी अंतर कर सकता है।

1

मुझे लगता है कि यह LINQ से XXXX प्रदाता के बारे में है। प्रदाता ने कौन लिखा था यह कह सकता है कि यह क्या कर सकता है (अनुकूलन और आदि के बारे में)। यहां तक ​​कि एक ही LINQ प्रदाता के दूसरे संस्करण में अलग-अलग परिणाम (केवल अनुवादों में) देना संभव है।

एक साधारण शब्द में LINQ प्रदाता केवल अनुवादक हैं, इसलिए आपको इस प्रश्न को LINQ प्रदाता के निर्माता से पूछना चाहिए जिसका आप अभी उपयोग करते हैं।

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