Je vois une performance vraiment étrange liée à une requête très simple utilisant Entity Framework Code-First avec .NET Framework version 4. La requête LINQ2Entities ressemble à ceci:
context.MyTables.Where(m => m.SomeStringProp == stringVar);
Cela prend plus de 3000 millisecondes à exécuter. Le SQL généré semble très simple:
SELECT [Extent1].[ID], [Extent1].[SomeStringProp], [Extent1].[SomeOtherProp],
...
FROM [MyTable] as [Extent1]
WHERE [Extent1].[SomeStringProp] = '1234567890'
Cette requête s'exécute presque instantanément lorsqu'elle est exécutée via Management Studio. Lorsque je change le code C # pour utiliser la fonction SqlQuery, il s'exécute dans 5 à 10 millisecondes:
context.MyTables.SqlQuery("SELECT [Extent1].[ID] ... WHERE [Extent1].[SomeStringProp] = @param", stringVar);
Donc, exactement le même SQL, les entités résultantes sont suivies des modifications dans les deux cas, mais une différence de performance sauvage entre les deux. Ce qui donne?
performance
entity-framework
ef-code-first
Brian Sullivan
la source
la source
Performance Considerations for Entity Framework 5
Réponses:
Je l'ai trouvé. Il s'avère que c'est un problème de types de données SQL. La
SomeStringProp
colonne de la base de données était un varchar, mais EF suppose que les types de chaîne .NET sont des nvarchars. Le processus de traduction résultant pendant la requête pour que la base de données effectue la comparaison est ce qui prend beaucoup de temps. Je pense que EF Prof m'égarait un peu ici, une représentation plus précise de la requête en cours d'exécution serait la suivante:Le correctif résultant consiste donc à annoter le modèle code-first, en indiquant le type de données SQL correct:
la source
varchar
pour tout, et c'était effectivement le problème. Je me demande si je peux créer un EDMX pour considérer varchar pour tout ce qui concerne la colonne de chaîne.La raison du ralentissement de mes requêtes effectuées dans EF était de comparer des scalaires non nullables avec des scalaires nullables:
Cette requête a pris 35 secondes. Mais un petit refactoring comme ça:
donne des résultats incroyables. Il n'a fallu que 50 ms pour terminer. Il est possible que ce soit un bogue dans EF.
la source
Si vous utilisez le mappage fluide, vous pouvez l'utiliser
IsUnicode(false)
dans le cadre de la configuration pour obtenir le même effet -http://msdn.microsoft.com/en-us/data/jj591617.aspx#1.9
http://msdn.microsoft.com/en-us/library/gg696416%28v=vs.103%29.aspx
la source
J'ai eu le même problème (la requête est rapide lorsqu'elle est exécutée à partir du gestionnaire SQL) mais lorsqu'elle est exécutée à partir d'EF, le délai expire.
Il s'avère que l'entité (qui a été créée à partir de la vue) avait de mauvaises clés d'entité. Ainsi, l'entité avait des lignes en double avec les mêmes clés, et je suppose qu'elle devait faire du regroupement en arrière-plan.
la source
Je suis également tombé sur cela avec une requête ef complexe. Un correctif pour moi qui a réduit une requête ef de 6 secondes à la sous-deuxième requête SQL qu'elle a générée était de désactiver le chargement différé.
Pour trouver ce paramètre (ef 6), allez dans le fichier .edmx et regardez dans Propriétés -> Génération de code -> Chargement différé activé. Défini sur false.
Amélioration massive des performances pour moi.
la source
J'ai eu ce problème aussi. Il s'avère que le coupable dans mon cas était le reniflement de paramètres SQL-Server .
Le premier indice que mon problème était en fait dû au reniflage de paramètres était que l'exécution de la requête avec «set arithabort off» ou «set arithabort on» donnait des temps d'exécution radicalement différents dans Management Studio. Cela est dû au fait qu'ADO.NET utilise par défaut «set arithabort off» et que Management Studio utilise par défaut «set arithabort on». Le cache du plan de requête conserve différents plans en fonction de ce paramètre.
J'ai désactivé la mise en cache du plan de requête pour la requête, avec la solution que vous pouvez trouver ici .
la source