नोट: मैंने यह उत्तर तब लिखा था जब Entity Framework 4 वास्तविक था। इस उत्तर की बात तुच्छ .Any()
बनाम .Count()
प्रदर्शन परीक्षण में नहीं थी। संकेत यह था कि ईएफ एकदम सही है। नए संस्करण बेहतर हैं ... लेकिन अगर आपके पास कोड का हिस्सा धीमा है और यह EF का उपयोग करता है, तो प्रत्यक्ष TSQL के साथ परीक्षण करें और मान्यताओं पर भरोसा करने के बजाय प्रदर्शन की तुलना करें (जो कि .Any()
हमेशा की तुलना में तेज़ है .Count() > 0
)।
हालांकि मैं अधिकांश मतदान-उत्तर और टिप्पणियों से सहमत हूं - विशेष रूप से पॉइंट Any
सिग्नल डेवलपर की मंशा से बेहतर है Count() > 0
- मेरे पास ऐसी स्थिति है जिसमें SQL सर्वर पर परिमाण के क्रम से गिनती तेज है (EntityFramework 4)।
यहाँ Any
उस समय समाप्ति अपवाद (~ 200.000 रिकॉर्ड पर) के साथ प्रश्न है :
con = db.Contacts.
Where(a => a.CompanyId == companyId && a.ContactStatusId <= (int) Const.ContactStatusEnum.Reactivated
&& !a.NewsletterLogs.Any(b => b.NewsletterLogTypeId == (int) Const.NewsletterLogTypeEnum.Unsubscr)
).OrderBy(a => a.ContactId).
Skip(position - 1).
Take(1).FirstOrDefault();
Count
मिलीसेकंड के मामले में निष्पादित संस्करण:
con = db.Contacts.
Where(a => a.CompanyId == companyId && a.ContactStatusId <= (int) Const.ContactStatusEnum.Reactivated
&& a.NewsletterLogs.Count(b => b.NewsletterLogTypeId == (int) Const.NewsletterLogTypeEnum.Unsubscr) == 0
).OrderBy(a => a.ContactId).
Skip(position - 1).
Take(1).FirstOrDefault();
मुझे यह देखने का एक तरीका खोजने की आवश्यकता है कि LINQs का सटीक एसक्यूएल दोनों क्या उत्पादन करते हैं - लेकिन यह स्पष्ट है कि कुछ मामलों में Count
और इसके बीच बहुत बड़ा प्रदर्शन अंतर है Any
, और दुर्भाग्य से ऐसा लगता है कि आप Any
सभी मामलों में बस नहीं टिक सकते ।
संपादित करें: यहाँ एसक्यूएल उत्पन्न होते हैं। सुंदरियों के रूप में आप देख सकते हैं;)
ANY
:
निष्पादित sp_executesql N'SELECT TOP (1)
[Project2]। [ContactId] AS [ContactId],
[Project2]। [CompanyId] AS [CompanyId],
[Project2]। [संपर्क नाम] के रूप में [ContactName],
[Project2]। [FullName] AS [FullName],
[Project2]। [ContactStatusId] AS [ContactStatusId],
[प्रोजेक्ट 2]। [बनाया गया] एएस [निर्मित]
FROM (SELECT [Project2]। [ContactId] AS [ContactId], [Project2]। [CompanyId] AS [CompanyId], [Project2], [ContactName] AS [ContactName], [Project2] [FullName] AS [FullName] के रूप में। , [Project2]। [ContactStatusId] AS [ContactStatusId], [Project2]। [बनाया गया] AS [बनाया गया], row_number () OVER (ORDER BY [Project2]] [ContactId] ASC) AS [row_number]।
FROM (Select
[Extent1]। [ContactId] AS [ContactId],
[एक्सटेंट 1]। [कंपनीआईड] एएस [कंपनीआईड],
[विस्तार 1]। [संपर्क नाम] के रूप में [संपर्क नाम],
[विस्तार 1]। [FullName] AS [FullName],
[Extent1]। [ContactStatusId] AS [ContactStatusId]]
[विस्तार १]। [बनाया गया] एएस [निर्मित]
[Dbo] से [संपर्क] AS [Extent1]
जहां ([एक्सटेंड 1]।
1 AS [C1]
[Dbo] से [न्यूज़लैटरलॉग] AS [Extent2]
WHERE ([एक्सटेंड 1]। [कांटेक्टआईड] = [एक्सटेंट 2]। [कॉन्टैक्टआईड]) और (6 = [एक्सटेंट 2]। [न्यूज़लैटरलॉगटाइप्ड]]
))
) के रूप में [Project2]
) के रूप में [Project2]
जहां [Project2]। [row_number]> 99
ORDER BY [Project2]। [ContactId] ASC ', N' @ p__linq__0 int ', @ p__linq__0 = 4
COUNT
:
निष्पादित sp_executesql N'SELECT TOP (1)
[Project2]। [ContactId] AS [ContactId],
[Project2]। [CompanyId] AS [CompanyId],
[Project2]। [संपर्क नाम] के रूप में [ContactName],
[Project2]। [FullName] AS [FullName],
[Project2]। [ContactStatusId] AS [ContactStatusId],
[प्रोजेक्ट 2]। [बनाया गया] एएस [निर्मित]
FROM (SELECT [Project2]। [ContactId] AS [ContactId], [Project2]। [CompanyId] AS [CompanyId], [Project2], [ContactName] AS [ContactName], [Project2] [FullName] AS [FullName] के रूप में। , [Project2]। [ContactStatusId] AS [ContactStatusId], [Project2]। [बनाया गया] AS [बनाया गया], row_number () OVER (ORDER BY [Project2]] [ContactId] ASC) AS [row_number]।
FROM (Select
[Project1]। [ContactId] AS [ContactId],
[Project1]। [CompanyId] AS [CompanyId],
[Project1]। [संपर्क नाम] के रूप में [ContactName],
[Project1]। [FullName] AS [FullName],
[Project1]। [ContactStatusId] AS [ContactStatusId],
[प्रोजेक्ट 1]। [बनाया गया] एएस [निर्मित]
FROM (Select
[Extent1]। [ContactId] AS [ContactId],
[एक्सटेंट 1]। [कंपनीआईड] एएस [कंपनीआईड],
[विस्तार 1]। [संपर्क नाम] के रूप में [संपर्क नाम],
[विस्तार 1]। [FullName] AS [FullName],
[Extent1]। [ContactStatusId] AS [ContactStatusId]
[विस्तार १]। [बनाया गया] एएस [निर्मित],
(चुनते हैं
COUNT (1) AS [A1]
[Dbo] से [न्यूज़लैटरलॉग] AS [Extent2]
WHERE ([Extent1]। [ContactId] = [Extent2]। [ContactId]) और (6 = [Extent2]। [NewsletterLogTypeId])) AS [C1]।
[Dbo] से [संपर्क] AS [Extent1]
) के रूप में [Project1]
WHERE ([Project1]। [CompanyId] = @ p__linq__0) AND ([Project1]। [ContactStatusId] <= 3) और (0 = [Project1]। [C1])
) के रूप में [Project2]
) के रूप में [Project2]
जहां [Project2]। [row_number]> 99
ORDER BY [Project2]। [ContactId] ASC ', N' @ p__linq__0 int ', @ p__linq__0 = 4
लगता है कि शुद्ध जहां EXISTS के साथ गणना की तुलना में बहुत बुरा काम करता है और फिर कहां गणना == 0 के साथ कर रहा है।
अगर आप लोग मेरे निष्कर्षों में कुछ त्रुटि देखते हैं तो मुझे बताएं। किसी भी बनाम गणना चर्चा की परवाह किए बिना इस सब से बाहर ले जाया जा सकता है कि किसी भी अधिक जटिल LINQ को बेहतर तरीके से बंद कर दिया जाता है जब संग्रहीत प्रक्रिया के रूप में फिर से लिखा जाता है;)।