หมายเหตุ:ฉันเขียนคำตอบนี้เมื่อ Entity Framework 4 เป็นจริง ประเด็นของคำตอบนี้ไม่ได้เป็นการทดสอบ.Any()
เทียบกับเรื่องเล็กน้อย .Count()
ประเด็นก็คือการส่งสัญญาณว่า EF นั้นไม่สมบูรณ์แบบ เวอร์ชันที่ใหม่กว่านั้นดีกว่า ... แต่ถ้าคุณมีส่วนหนึ่งของรหัสที่ช้าและใช้ EF ทดสอบกับ TSQL โดยตรงและเปรียบเทียบประสิทธิภาพแทนที่จะพึ่งพาสมมติฐาน (นั่น.Any()
คือเร็วกว่าเสมอ.Count() > 0
)
ในขณะที่ฉันเห็นด้วยกับคำตอบและข้อคิดเห็นที่ได้รับการโหวตมากที่สุดโดยเฉพาะอย่างยิ่งในจุดAny
ส่งสัญญาณความตั้งใจของนักพัฒนาที่ดีกว่าCount() > 0
- ฉันเคยมีสถานการณ์ที่ Count เร็วขึ้นตามลำดับความสำคัญบน SQL Server (EntityFramework 4)
นี่คือข้อความค้นหาที่มีAny
ข้อยกเว้นการหมดเวลาของ thew (ใน ~ 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();
ฉันต้องการหาวิธีที่จะดูว่า SQL ที่แน่นอนทั้ง LINQs ผลิต - แต่มันชัดเจนว่ามีความแตกต่างอย่างมากระหว่างCount
และAny
ในบางกรณีและโชคไม่ดีที่ดูเหมือนว่าคุณไม่สามารถติดกับAny
ทุกกรณี
แก้ไข: นี่คือ SQL ที่สร้างขึ้น ความงามที่คุณเห็น;)
ANY
:
exec sp_executesql N'SELECT ด้านบน (1)
[Project2]. [ContactId] AS [ContactId],
[Project2]. [CompanyId] AS [CompanyId],
[Project2]. [ContactName] AS [ContactName]
[Project2]. [FullName] AS [FullName]
[Project2]. [ContactStatusId] AS [ContactStatusId],
[Project2]. [สร้าง] AS [สร้าง]
จาก (เลือก [Project2]. [ContactId] AS [ContactId], [Project2]. [CompanyId] AS [CompanyId], [Project2]. [ContactName] AS [ContactName], [Project2]. [FullName] AS [FullName] , [Project2]. [ContactStatusId] AS [ContactStatusId], [Project2]. [สร้าง] AS [สร้าง], row_number () ขึ้นไป (เรียงตาม [Project2]. [ContactId] ASC) AS [row_number]
จาก (เลือก
[Extent1]. [ContactId] AS [ContactId],
[Extent1]. [CompanyId] AS [CompanyId],
[Extent1]. [ContactName] เป็น [ContactName],
[Extent1]. [FullName] AS [FullName]
[Extent1]. [ContactStatusId] AS [ContactStatusId],
[Extent1]. [สร้าง] AS [สร้าง]
จาก [dbo] [ติดต่อ] AS [Extent1]
WHERE ([Extent1]. [CompanyId] = @ p__linq__0) และ ([Extent1]. [ContactStatusId] <= 3) และ (ไม่ใช่ EXISTS (เลือก
1 AS [C1]
จาก [dbo]. [NewsletterLog] AS [Extent2]
WHERE ([Extent1]. [ContactId] = [Extent2]. [ContactId]) และ (6 = [Extent2]. [NewsletterLogTypeId])
))
) AS [โครงการ 2]
) AS [โครงการ 2]
WHERE [Project2]. [row_number]> 99
เรียงตาม [Project2]. [ContactId] ASC ', N' @ p__linq__0 int ', @ p__linq__0 = 4
COUNT
:
exec sp_executesql N'SELECT ด้านบน (1)
[Project2]. [ContactId] AS [ContactId],
[Project2]. [CompanyId] AS [CompanyId],
[Project2]. [ContactName] AS [ContactName]
[Project2]. [FullName] AS [FullName]
[Project2]. [ContactStatusId] AS [ContactStatusId],
[Project2]. [สร้าง] AS [สร้าง]
จาก (เลือก [Project2]. [ContactId] AS [ContactId], [Project2]. [CompanyId] AS [CompanyId], [Project2]. [ContactName] AS [ContactName], [Project2]. [FullName] AS [FullName] , [Project2]. [ContactStatusId] AS [ContactStatusId], [Project2]. [สร้าง] AS [สร้าง], row_number () ขึ้นไป (เรียงตาม [Project2]. [ContactId] ASC) AS [row_number]
จาก (เลือก
[Project1]. [ContactId] AS [ContactId],
[Project1]. [CompanyId] AS [CompanyId],
[Project1]. [ContactName] AS [ContactName]
[Project1]. [FullName] AS [FullName]
[Project1]. [ContactStatusId] AS [ContactStatusId],
[Project1]. [สร้าง] AS [สร้าง]
จาก (เลือก
[Extent1]. [ContactId] AS [ContactId],
[Extent1]. [CompanyId] AS [CompanyId],
[Extent1]. [ContactName] เป็น [ContactName],
[Extent1]. [FullName] AS [FullName]
[Extent1]. [ContactStatusId] AS [ContactStatusId],
[Extent1]. [สร้าง] AS [สร้าง],
(เลือก
COUNT (1) AS [A1]
จาก [dbo]. [NewsletterLog] AS [Extent2]
WHERE ([Extent1]. [ContactId] = [Extent2]. [ContactId]) และ (6 = [Extent2]. [NewsletterLogTypeId])) AS [C1]
จาก [dbo] [ติดต่อ] AS [Extent1]
) AS [โครงการ 1]
WHERE ([Project1]. [CompanyId] = @ p__linq__0) และ ([Project1]. [ContactStatusId] <= 3) AND (0 = [Project1]. [C1])
) AS [โครงการ 2]
) AS [โครงการ 2]
WHERE [Project2]. [row_number]> 99
เรียงตาม [Project2]. [ContactId] ASC ', N' @ p__linq__0 int ', @ p__linq__0 = 4
ดูเหมือนว่าบริสุทธิ์โดยที่ EXISTS ทำงานได้แย่กว่าการคำนวณ Count จากนั้นทำ Where With Count == 0
แจ้งให้เราทราบหากพวกคุณเห็นข้อผิดพลาดในการค้นพบของฉัน สิ่งที่สามารถนำออกมาได้ทั้งหมดนี้โดยไม่คำนึงถึงการสนทนาใด ๆ กับการนับจำนวนคือ LINQ ที่ซับซ้อนมากขึ้นนั้นดีกว่าเมื่อเขียนใหม่ในรูปแบบ Stored Procedure;)