Contient() d'Entity Framework : goulot d'étranglement des performances avec de grands ensembles de données
L'utilisation de la méthode Contains()
d'Entity Framework avec des ensembles de données étendus peut avoir un impact important sur les performances. Cela découle de sa traduction en une série d'instructions OU dans le SQL généré, ce qui devient inefficace lorsqu'il s'agit de nombreuses comparaisons.
Considérez cet exemple :
<code class="language-csharp">var ids = Main.Select(a => a.Id).ToArray(); var rows = Main.Where(a => ids.Contains(a.Id)).ToArray();</code>
Une comparaison impliquant une table de 10 000 enregistrements et un tableau de 100 éléments peut être jusqu'à 288 fois plus lente qu'une simple requête LINQ récupérant toutes les lignes. La cause première réside dans le manque de prise en charge native par ADO.NET des expressions IN. La solution de contournement d'EF (un arbre d'expression OR complexe) est coûteuse en termes de calcul pour les grands ensembles d'entrées.
Solutions et stratégies
L'approche optimale consiste à exploiter l'opérateur In()
, car il est pris en charge de manière native par les fournisseurs ADO.NET, ce qui conduit à un SQL plus efficace.
Si In()
n'est pas réalisable, envisagez ces alternatives :
CompiledQuery
nécessite des types de données fondamentaux. Pour l'utiliser avec des tableaux ou IEnumerable
, créez une fonction personnalisée convertissant l'entrée en un type fondamental (par exemple, une chaîne séparée par des virgules). Cette chaîne convertie peut ensuite être utilisée dans un CompiledQuery
employant l'opérateur In()
.Regard vers l'avenir
L'équipe Entity Framework est consciente de cette limitation de performances et explore la prise en charge native des expressions IN dans le modèle de fournisseur. Cette amélioration améliorerait considérablement les Contains()
performances pour les grands ensembles de données.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!