ホームページ >データベース >mysql チュートリアル >「IEnumerable.Contains()」 が Entity Framework のパフォーマンスに大きな影響を与えるのはなぜですか?
Entity Framework のパフォーマンスのボトルネック: IEnumerable.Contains()
Entity Framework (EF) で Enumerable.Contains()
を使用すると、多くの場合、重大なパフォーマンスの問題が発生します。 これは、EF のプロバイダーが SQL IN
演算子を直接サポートしていないためです。 代わりに、Contains()
を一連の OR
条件に変換するため、大規模なデータセットでは非常に非効率的になります。
パフォーマンスへの影響を理解する
典型的なシナリオを見てみましょう:
<code class="language-csharp">var ids = Main.Select(a => a.Id).ToArray(); var rows = Main.Where(a => ids.Contains(a.Id)).ToArray();</code>
EF は、これを次のような最適とは言えない SQL クエリに変換します。
<code class="language-sql">SELECT [Extent1].[Id] AS [Id] FROM [dbo].[Primary] AS [Extent1] WHERE [Extent1].[Id] = 1 OR [Extent1].[Id] = 2 OR [Extent1].[Id] = 3 ...</code>
この OR
句の連鎖がパフォーマンス低下の根本原因です。
パフォーマンス最適化のための戦略
いくつかの方法でこのパフォーマンスの問題を軽減できます。
DbSet.Contains()
の利用 (EF Core): EF Core では、一般に DbSet.Contains()
よりも DbSet で Enumerable.Contains()
を直接使用することが推奨されます。 これにより、EF Core はクエリを効率的な IN
句に変換できるようになります。
InExpression
(EF6) を使用します: EF6 では、InExpression
句を明示的にサポートするために IN
を導入し、より直接的かつ効率的な変換を提供します。
データのチャンク化: 上記のオプションのどちらも実行できない場合は、入力データをより小さなチャンクに分割します。 各チャンクを個別に処理し、複数のより小さい IN
クエリを生成します。これにより、個々のクエリの複雑さが軽減されます。
生の SQL クエリ: 最後の手段として、IN
演算子を使用してカスタム SQL クエリを作成して、LINQ と EF を完全にバイパスします。 これにより、最大限の制御が提供されますが、EF の ORM の利点が犠牲になります。
代替アプローチ: Contains()
を完全に不要にする代替クエリ構造を検討してください。 これには、データベース クエリの再構築や、さまざまなデータ アクセス手法の採用が含まれる場合があります。
これらのソリューションのいずれかを実装すると、大規模なデータセットや Contains()
操作を処理する際の Entity Framework クエリのパフォーマンスを大幅に向上させることができます。
以上が「IEnumerable.Contains()」 が Entity Framework のパフォーマンスに大きな影響を与えるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。