참고 : Entity Framework 4가 실제 일 때이 답변을 썼습니다. 이 답변의 요점은 사소한에 들어갈 아니었다 .Any()
대 .Count()
성능 테스트. 요점은 EF가 완벽하지 않다는 신호였다. 최신 버전이 더 낫지 만 ... 코드의 속도가 느리고 EF를 사용하는 경우 가정에 의존하지 않고 직접 TSQL로 테스트하고 성능을 비교하십시오 ( .Any()
항상보다 빠름 .Count() > 0
).
특히 개발자가 의도 한 것보다 더 나은 Any
신호 에 대해 가장 많이 찬성 된 답변과 의견에 동의하지만 SQL Server에서 Count가 더 빠르다는 상황이있었습니다 (EntityFramework 4).Count() > 0
다음은 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();
나는 정확한 SQL 모두 LINQs 생산 무엇을 볼 수있는 방법을 찾아야 -하지만 사이에 큰 성능 차이가 명백 Count
하고 Any
경우에 따라서는, 불행하게도 당신이 단지 고집 할 수없는 것 같습니다 Any
모든 경우입니다.
편집 : 여기에 생성 된 SQL이 있습니다. 당신이 볼 수 있듯이 아름다움;)
ANY
:
exec sp_executesql N'SELECT TOP (1)
[프로젝트 2]. [ContactId] AS [ContactId],
[프로젝트 2]. [회사 ID] AS [회사 ID],
[프로젝트 2]. [ContactName] AS [ContactName],
[프로젝트 2]. [FullName] AS [FullName],
[Project2]. [ContactStatusId] AS [ContactStatusId],
[프로젝트 2]. [만든] AS [만든]
FROM (SELECT [Project2]. [ContactId] AS [ContactId], [Project2]. [CompanyId] AS [CompanyId], [Project2]. [ContactName] AS [ContactName], [Project2]. [FullName] AS [FullName] , [Project2]. [ContactStatusId] AS [ContactStatusId], [Project2]. [Created] AS [Created], row_number () OVER (ORDER BY [Project2]. [ContactId] ASC) AS [row_number]
FROM (선택
[Extent1]. [ContactId] AS [ContactId],
[Extent1]. [회사 ID] AS [회사 ID],
[Extent1]. [ContactName] AS [ContactName],
[Extent1]. [FullName] AS [FullName],
[Extent1]. [ContactStatusId] AS [ContactStatusId],
[Extent1]. [만든] AS [만든]
[dbo]에서. [문의] AS [Extent1]
([Extent1]. [CompanyId] = @ p__linq__0) AND ([Extent1]. [ContactStatusId] <= 3) AND (존재하지 않음 (SELECT
1 AS [C1]
[dbo]에서. [뉴스 레터 로그] AS [Extent2]
([Extent1]. [ContactId] = [Extent2]. [ContactId]) 및 (6 = [Extent2]. [NewsletterLogTypeId])
))
) AS [프로젝트 2]
) AS [프로젝트 2]
어디에 [프로젝트 2]. [행 번호]> 99
[프로젝트 2]에 의한 주문. [ContactId] ASC ', N'@ p__linq__0 int ', @ p__linq__0 = 4
COUNT
:
exec sp_executesql N'SELECT TOP (1)
[프로젝트 2]. [ContactId] AS [ContactId],
[프로젝트 2]. [회사 ID] AS [회사 ID],
[프로젝트 2]. [ContactName] AS [ContactName],
[프로젝트 2]. [FullName] AS [FullName],
[Project2]. [ContactStatusId] AS [ContactStatusId],
[프로젝트 2]. [만든] AS [만든]
FROM (SELECT [Project2]. [ContactId] AS [ContactId], [Project2]. [CompanyId] AS [CompanyId], [Project2]. [ContactName] AS [ContactName], [Project2]. [FullName] AS [FullName] , [Project2]. [ContactStatusId] AS [ContactStatusId], [Project2]. [Created] AS [Created], row_number () OVER (ORDER BY [Project2]. [ContactId] ASC) AS [row_number]
FROM (선택
[프로젝트 1]. [ContactId] AS [ContactId],
[프로젝트 1]. [회사 ID] AS [회사 ID],
[프로젝트 1]. [ContactName] AS [ContactName],
[프로젝트 1]. [FullName] AS [FullName],
[Project1]. [ContactStatusId] AS [ContactStatusId],
[프로젝트 1]. [만든] AS [만든]
FROM (선택
[Extent1]. [ContactId] AS [ContactId],
[Extent1]. [회사 ID] AS [회사 ID],
[Extent1]. [ContactName] AS [ContactName],
[Extent1]. [FullName] AS [FullName],
[Extent1]. [ContactStatusId] AS [ContactStatusId],
[Extent1]. [만든] AS [만든],
(고르다
COUNT (1)대로 [A1]
[dbo]에서. [뉴스 레터 로그] AS [Extent2]
WHERE ([Extent1]. [ContactId] = [Extent2]. [ContactId]) 및 (6 = [Extent2]. [NewsletterLogTypeId])) AS [C1]
[dbo]에서. [문의] AS [Extent1]
) AS [프로젝트 1]
([Project1]. [CompanyId] = @ p__linq__0) AND ([Project1]. [ContactStatusId] <= 3) AND (0 = [프로젝트 1]. [C1])
) AS [프로젝트 2]
) AS [프로젝트 2]
어디에 [프로젝트 2]. [행 번호]> 99
[프로젝트 2]에 의한 주문. [ContactId] ASC ', N'@ p__linq__0 int ', @ p__linq__0 = 4
EXISTS를 사용한 순수한 위치는 Count를 계산 한 다음 Count == 0으로 Where를 수행하는 것보다 훨씬 나쁩니다.
내 결과에 약간의 오류가 있는지 알려주십시오. Any vs Count 토론에 관계없이이 모든 것을 제거 할 수있는 것은 더 복잡한 LINQ가 Stored Procedure;