注:この回答は、Entity Framework 4が実際にあったときに書きました。この回答のポイントは些細に入るためにはなかった.Any()
対.Count()
性能試験。ポイントは、EFが完璧とはほど遠いことを示すことでした。新しいバージョンの方が優れていますが、コードの一部に低速でEFを使用している場合は、前提条件に依存するのではなく、直接TSQLでテストし、パフォーマンスを比較します(.Any()
常により高速です.Count() > 0
)。
私は同意するものの、ほとんどの回答やコメントをアップでは、投票-特にポイントにAny
信号の意思開発者よりも良いCount() > 0
-私はカウントがSQL Serverの(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();
私は正確なSQLの両方LINQsが作り出すかを確認する方法を見つける必要がある-それは間に大きなパフォーマンスの差がある明らかだCount
し、Any
いくつかのケースでは、残念ながらそれはあなただけに固執することはできませんと思われるAny
すべてのケースインチ
編集:生成されたSQLを以下に示します。あなたが見ることができる美しさ;)
ANY
:
exec sp_executesql N'SELECT TOP(1)
[Project2]。[ContactId] AS [ContactId]、
[Project2]。[CompanyId] AS [CompanyId]、
[Project2]。[ContactName] AS [ContactName]、
[Project2]。[FullName] AS [FullName]、
[Project2]。[ContactStatusId] AS [ContactStatusId]、
[Project2]。[Created] AS [Created]
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(SELECT
[Extent1]。[ContactId] AS [ContactId]、
[Extent1]。[CompanyId] AS [CompanyId]、
[Extent1]。[ContactName] AS [ContactName]、
[Extent1]。[FullName] AS [FullName]、
[Extent1]。[ContactStatusId] AS [ContactStatusId]、
[Extent1]。[Created] AS [Created]
FROM [dbo]。[Contact] AS [Extent1]
WHERE([Extent1]。[CompanyId] = @ p__linq__0)AND([Extent1]。[ContactStatusId] <= 3)AND(NOT EXISTS(SELECT
1 AS [C1]
FROM [dbo]。[NewsletterLog] AS [Extent2]
WHERE([Extent1]。[ContactId] = [Extent2]。[ContactId])AND(6 = [Extent2]。[NewsletterLogTypeId])
))
)AS [Project2]
)AS [Project2]
WHERE [Project2]。[row_number]> 99
ORDER BY [Project2]。[ContactId] ASC '、N' @ p__linq__0 int '、@ p__linq__0 = 4
COUNT
:
exec sp_executesql N'SELECT TOP(1)
[Project2]。[ContactId] AS [ContactId]、
[Project2]。[CompanyId] AS [CompanyId]、
[Project2]。[ContactName] AS [ContactName]、
[Project2]。[FullName] AS [FullName]、
[Project2]。[ContactStatusId] AS [ContactStatusId]、
[Project2]。[Created] AS [Created]
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(SELECT
[Project1]。[ContactId] AS [ContactId]、
[Project1]。[CompanyId] AS [CompanyId]、
[Project1]。[ContactName] AS [ContactName]、
[Project1]。[FullName] AS [FullName]、
[Project1]。[ContactStatusId] AS [ContactStatusId]、
[Project1]。[Created] AS [Created]
FROM(SELECT
[Extent1]。[ContactId] AS [ContactId]、
[Extent1]。[CompanyId] AS [CompanyId]、
[Extent1]。[ContactName] AS [ContactName]、
[Extent1]。[FullName] AS [FullName]、
[Extent1]。[ContactStatusId] AS [ContactStatusId]、
[Extent1]。[Created] AS [Created]、
(選択する
COUNT(1)AS [A1]
FROM [dbo]。[NewsletterLog] AS [Extent2]
WHERE([Extent1]。[ContactId] = [Extent2]。[ContactId])AND(6 = [Extent2]。[NewsletterLogTypeId]))AS [C1]
FROM [dbo]。[Contact] AS [Extent1]
)AS [Project1]
WHERE([Project1]。[CompanyId] = @ p__linq__0)AND([Project1]。[ContactStatusId] <= 3)AND(0 = [Project1]。[C1])
)AS [Project2]
)AS [Project2]
WHERE [Project2]。[row_number]> 99
ORDER BY [Project2]。[ContactId] ASC '、N' @ p__linq__0 int '、@ p__linq__0 = 4
純粋なWhere with EXISTSは、Countを計算してからWhere = Count == 0を実行するよりもはるかに悪いようです。
私の調査結果にエラーがあったら教えてください。Any vs Countの議論に関係なく、これからすべてを取り除くことができるのは、より複雑なLINQは、ストアドプロシージャとして書き換えた方がずっとよいことです;)。