web-dev-qa-db-fra.com

Comment le cadre d'entité fonctionne-t-il pour un grand nombre d'enregistrements?

Je vois déjà une question sans réponse ici .

Ma question est -

EF est-il vraiment prêt à être utilisé dans les grandes applications?

La question provenait de ces questions sous-jacentes -

  1. EF enregistre tous les enregistrements en mémoire, puis effectue l'opération de requête. Comment EF se comporterait lorsque la table contient environ 1 000 enregistrements?
  2. Pour une édition simple, je dois extraire l'enregistrement, puis l'enfoncer à la base de données en utilisant SaveChanges()
51
Abhijeet

J'ai été confronté à une situation similaire dans laquelle nous avions une base de données volumineuse contenant de nombreuses tables, entre 7 et 10 millions d'enregistrements. nous avons utilisé Entity Framework pour afficher les données. Pour obtenir de belles performances, voici ce que j'ai appris. Mes 10 règles d'or pour Entity Framework:

  1. Comprenez que l’appel à la base de données n’est effectué que lorsque les enregistrements réels sont requis. toutes les opérations ne sont utilisées que pour créer la requête (SQL). Essayez donc d'extraire uniquement une donnée plutôt que de demander un grand nombre d'enregistrements. Réduisez la taille de fetch autant que possible

  2. Oui, (dans certains cas, les procédures stockées sont un meilleur choix, elles ne sont pas si mauvaises que certains vous le font croire), vous devez utiliser des procédures stockées si nécessaire. Importez-les dans votre modèle et importez-les par fonction. Vous pouvez également les appeler directement ExecuteStoreCommand (), ExecuteStoreQuery <> (). Il en va de même pour les fonctions et les vues, mais EF dispose d’un moyen très étrange d’appeler les fonctions "SELECT dbo.blah (@id)".

  3. EF est plus lent lorsqu'il doit peupler une entité avec une hiérarchie profonde. être extrêmement prudent avec les entités avec une hiérarchie profonde

  4. Parfois, lorsque vous demandez des enregistrements et que vous n'êtes pas obligé de les modifier, vous devez indiquer à EF de ne pas surveiller les modifications de propriété (AutoDetectChanges). de cette façon, la récupération des enregistrements est beaucoup plus rapide

  5. L'indexation de la base de données est bonne, mais dans le cas de EF, cela devient très important. Les colonnes que vous utilisez pour la récupération et le tri doivent être correctement indexées.

  6. Lorsque votre modèle est volumineux, le concepteur de modèles VS2010/VS2012 devient vraiment fou. alors divisez votre modèle en modèles de taille moyenne. Il existe une limite au fait que les entités de différents modèles ne peuvent pas être partagées même si elles pointent vers la même table dans la base de données.

  7. Lorsque vous devez apporter des modifications à la même entité à différents endroits, utilisez la même entité, apportez des modifications et enregistrez-la une seule fois. Le but est d’ÉVITER de récupérer le même enregistrement, d’apporter des modifications et de l’enregistrer plusieurs fois. (Astuce de gain de performance réelle).

  8. Lorsque vous avez besoin des informations dans une ou deux colonnes seulement, essayez de ne pas extraire l'entité complète. vous pouvez soit exécuter votre sql directement, soit créer une mini-entité. Vous devrez peut-être également mettre en cache des données fréquemment utilisées dans votre application.

  9. Les transactions sont lentes. soyez prudent avec eux.

  10. SQL Profiler ou tout profileur de requête est votre ami. Exécutez-le lorsque vous développez votre application pour voir ce que EF envoie à la base de données. Lorsque vous effectuez une jointure à l'aide de l'expression LINQ ou Lambda dans votre application, EF génère généralement une requête de style Sélectionner-où-dans-la-sélection qui peut ne pas toujours fonctionner correctement. Si vous trouvez un tel cas, retroussez vos manches, effectuez la jointure sur une base de données et récupérez les résultats avec EF. (J'ai oublié celui-ci, le plus important!)

si vous gardez cela à l'esprit, EF devrait offrir des performances presque similaires à celles d'un ADO.NET standard, sinon identiques.

130
Simple Fellow

1. EF enregistre tous les enregistrements en mémoire, puis effectue l’interrogation. Comment EF se comporterait lorsque la table contient environ 1 000 enregistrements?

Ce n'est pas vrai! EF ne récupère que les enregistrements nécessaires et les requêtes sont transformées en instructions SQL appropriées. EF peut mettre en cache des objets localement dans DataContext (et suivre toutes les modifications apportées aux entités), mais tant que vous suivez la règle pour que le contexte reste ouvert uniquement lorsque cela est nécessaire, cela ne posera pas de problème.

2. Pour une modification simple, je dois extraire la fiche, la modifier, puis appuyer sur db à l'aide de SaveChanges ().

C’est vrai, mais je n’en aurais pas la peine, sauf si vous voyez vraiment les problèmes de performances. Parce que 1. n'est pas vrai, vous n'obtiendrez qu'un seul enregistrement de la base de données avant son enregistrement. Vous pouvez éviter cela en créant la requête SQL en tant que chaîne et en l'envoyant en tant que chaîne simple.

19
MarcinJuraszek
  1. EF convertit votre requête LINQ en requête SQL afin de ne pas extraire tous les enregistrements en mémoire. Le code SQL généré n’est peut-être pas toujours le plus efficace, mais un millier d’enregistrements ne pose aucun problème.
  2. Oui, c'est une façon de le faire (en supposant que vous ne vouliez éditer qu'un seul enregistrement). Si vous modifiez plusieurs enregistrements, vous pouvez tous les obtenir en utilisant une requête et SaveChanges() conservera tous ces changements.
6
Botz3000

EF n'est pas un mauvais framework ORM. C'est un différent avec ses propres caractéristiques. Comparez Microsoft Entity Framework 6 à NetTiers, par exemple, qui est optimisé par Microsoft Enterprise Library 6.

Ce sont deux bêtes complètement différentes. La réponse acceptée est vraiment bonne car elle passe par les nuances de EF6. Il est essentiel de comprendre que chaque ORM a ses propres forces et faiblesses. Comparez les exigences du projet et ses modèles d'accès aux données aux modèles de comportement de l'ORM.

Par exemple: NetTiers vous donnera toujours une performance brute supérieure à EF6. Cependant, c’est principalement parce qu’il ne s’agit pas d’un ORM de pointer et de faire partie intégrante de la génération de l’ORM, vous optimiserez votre modèle de données en ajoutant des procédures stockées personnalisées, le cas échéant, etc. si vous avez conçu votre modèle de données avec le même effort pour EF6, vous pourriez probablement vous rapprocher de la même performance.

Pensez-vous également que vous pouvez modifier l'ORM? Par exemple, avec NetTiers, vous pouvez ajouter des extensions aux modèles Codesmith pour inclure vos propres modèles de conception, en plus de ce qui est généré par la bibliothèque de base ORM.

Considérez également que EF6 utilise beaucoup la réflexion, tandis que NetTiers ou toute bibliothèque utilisant Microsoft Enterprise Library utilise beaucoup Generics. Ce sont deux approches totalement différentes. Pourquoi Parce que EF6 est basé sur une réflexion dynamique alors que NetTiers est basé sur une réflexion statique. Ce qui est plus rapide et ce qui est mieux dépend entièrement des modèles d'utilisation qui seront requis de l'ORM.

Parfois, une approche hybride donne de meilleurs résultats: considérons par exemple les points de terminaison OData EF6 pour Web API, Quelques grandes tables encapsulées avec NetTiers & Microsoft Enterprise Library avec des procédures stockées personnalisées, et quelques grandes tables de données maîtresses encapsulées avec un cache d’objets en écriture construit sur mesure chargement initial, le jeu d’enregistrements est transféré dans la mémoire cache à l’aide d’un lecteur de données ADO).

Ce sont tous différents et ils ont tous leurs meilleurs scénarios d'ajustement: EF6, NetTiers, NHibernate, Wilson OR Mapper, XPO de Dev Express, etc ...

5
tcwicks

Il n'y a pas de réponse simple à votre question. L'essentiel est de savoir ce que vous voulez faire avec vos données? Et avez-vous besoin de tant de données en même temps?

EF a traduit vos requêtes en SQL afin qu'aucun objet ne soit en mémoire pour le moment. Lorsque vous obtenez les données, les enregistrements sélectionnés sont en mémoire. Si vous sélectionnez une grande quantité d’objets de grande taille, il peut s’avérer très efficace si vous devez tous les manipuler.

Si vous n'avez pas besoin de tous les manipuler, vous pouvez désactiver le suivi des modifications et l'activer ultérieurement pour des objets uniques que vous devez manipuler.

Donc, vous voyez que cela dépend de votre type d'application. Si vous devez manipuler une masse de données efficace, n'utilisez pas d'OR-Mapper!

Sinon, EF convient, mais réfléchissez au nombre d'objets dont vous avez réellement besoin en même temps et à ce que vous voulez en faire.

4
Dannydust