0
votes

Slow Save dans le cadre d'entité, une entité très spécifique

J'ai un problème très intéressant (et déroutant) pendant un certain temps, mais je ne peux pas aller au bas de celui-ci

​​J'ai un projet code> du projet code> intégré sur cadre d'entité code>, avec environ 100 entités / tables différentes, qui fonctionnent tous en douceur. À l'exception d'un type d'entité, Named SaleProduct P>

Sauvegarde d'un produit de vente prend environ 5 minutes, parfois encore plus (les autres entités prennent moins de 2 secondes généralement). Et seulement dans la fenêtre. P>

à des fins de test, je mets ce code dans l'application Démarrage: P>

[Managed to Native Transition]  
    System.Data.dll!SNINativeMethodWrapper.SNIReadSyncOverAsync(System.Runtime.InteropServices.SafeHandle pConn, ref System.IntPtr packet, int timeout) Unknown
    System.Data.dll!System.Data.SqlClient.TdsParserStateObject.ReadSniSyncOverAsync()   Unknown
    System.Data.dll!System.Data.SqlClient.TdsParserStateObject.TryReadNetworkPacket()   Unknown
    System.Data.dll!System.Data.SqlClient.TdsParserStateObject.TryPrepareBuffer()   Unknown
    System.Data.dll!System.Data.SqlClient.TdsParserStateObject.TryReadByte(out byte value)  Unknown
    System.Data.dll!System.Data.SqlClient.TdsParser.TryRun(System.Data.SqlClient.RunBehavior runBehavior, System.Data.SqlClient.SqlCommand cmdHandler, System.Data.SqlClient.SqlDataReader dataStream, System.Data.SqlClient.BulkCopySimpleResultSet bulkCopyHandler, System.Data.SqlClient.TdsParserStateObject stateObj, out bool dataReady)  Unknown
    System.Data.dll!System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()    Unknown
    System.Data.dll!System.Data.SqlClient.SqlDataReader.MetaData.get()  Unknown
    System.Data.dll!System.Data.SqlClient.SqlCommand.FinishExecuteReader(System.Data.SqlClient.SqlDataReader ds, System.Data.SqlClient.RunBehavior runBehavior, string resetOptionsString, bool isInternal, bool forDescribeParameterEncryption, bool shouldCacheForAlwaysEncrypted)    Unknown
    System.Data.dll!System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(System.Data.CommandBehavior cmdBehavior, System.Data.SqlClient.RunBehavior runBehavior, bool returnStream, bool async, int timeout, out System.Threading.Tasks.Task task, bool asyncWrite, bool inRetry, System.Data.SqlClient.SqlDataReader ds, bool describeParameterEncryptionRequest)  Unknown
    System.Data.dll!System.Data.SqlClient.SqlCommand.RunExecuteReader(System.Data.CommandBehavior cmdBehavior, System.Data.SqlClient.RunBehavior runBehavior, bool returnStream, string method, System.Threading.Tasks.TaskCompletionSource<object> completion, int timeout, out System.Threading.Tasks.Task task, out bool usedCache, bool asyncWrite, bool inRetry)   Unknown
    System.Data.dll!System.Data.SqlClient.SqlCommand.RunExecuteReader(System.Data.CommandBehavior cmdBehavior, System.Data.SqlClient.RunBehavior runBehavior, bool returnStream, string method) Unknown
    System.Data.dll!System.Data.SqlClient.SqlCommand.ExecuteReader(System.Data.CommandBehavior behavior, string method) Unknown
>   EntityFramework.dll!System.Data.Entity.Infrastructure.Interception.InternalDispatcher<System.Data.Entity.Infrastructure.Interception.IDbCommandInterceptor>.Dispatch<System.Data.Common.DbCommand, System.Data.Entity.Infrastructure.Interception.DbCommandInterceptionContext<System.Data.Common.DbDataReader>, System.Data.Common.DbDataReader>(System.Data.Common.DbCommand target, System.Func<System.Data.Common.DbCommand, System.Data.Entity.Infrastructure.Interception.DbCommandInterceptionContext<System.Data.Common.DbDataReader>, System.Data.Common.DbDataReader> operation, System.Data.Entity.Infrastructure.Interception.DbCommandInterceptionContext<System.Data.Common.DbDataReader> interceptionContext, System.Action<System.Data.Entity.Infrastructure.Interception.IDbCommandInterceptor, System.Data.Common.DbCommand, System.Data.Entity.Infrastructure.Interception.DbCommandInterceptionContext<System.Data.Common.DbDataReader>> executing, System.Action<System.Data.Entity.Infrastructure.Interception.IDbCommandInterceptor, System.Data.Common.DbCommand, System.Data.Entity.Infrastructure.Interception.DbCommandInterceptionContext<System.Data.Common.DbDataReader>> executed) Line 138  C#
    EntityFramework.dll!System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(System.Data.Common.DbCommand command, System.Data.Entity.Infrastructure.Interception.DbCommandInterceptionContext interceptionContext) Line 103   C#
    EntityFramework.dll!System.Data.Entity.Core.Mapping.Update.Internal.DynamicUpdateCommand.Execute(System.Collections.Generic.Dictionary<int, object> identifierValues, System.Collections.Generic.List<System.Collections.Generic.KeyValuePair<System.Data.Entity.Core.Mapping.Update.Internal.PropagatorResult, object>> generatedValues) Line 118  C#
    EntityFramework.dll!System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update() Line 532  C#
    EntityFramework.dll!System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction<int>(System.Func<int> func, System.Data.Entity.Infrastructure.IDbExecutionStrategy executionStrategy, bool startLocalTransaction, bool releaseConnectionOnSuccess) Line 2203 C#
    EntityFramework.dll!System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(System.Data.Entity.Core.Objects.SaveOptions options, System.Data.Entity.Infrastructure.IDbExecutionStrategy executionStrategy, bool startLocalTransaction) Line 2148   C#
    EntityFramework.SqlServer.dll!System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute<int>(System.Func<int> operation) Unknown
    EntityFramework.dll!System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(System.Data.Entity.Core.Objects.SaveOptions options, bool executeInExistingTransaction) Line 2046 C#
    EntityFramework.dll!System.Data.Entity.Internal.InternalContext.SaveChanges() Line 483  C#
    Machshevet.dll!Machshevet.Core.RecordContext.SaveChanges() Line 762 Basic
    Machshevet.dll!Machshevet.Windows.RecordWindow.Save() Line 169  Basic
    Machshevet.dll!Machshevet.Windows.RecordWindow.<closure>.<lambda35-0>() Line 44 Basic
    PresentationCore.dll!System.Windows.Input.CommandBinding.OnExecuted(object sender, System.Windows.Input.ExecutedRoutedEventArgs e)  Unknown
    PresentationCore.dll!System.Windows.Input.CommandManager.ExecuteCommandBinding(object sender, System.Windows.Input.ExecutedRoutedEventArgs e, System.Windows.Input.CommandBinding commandBinding)   Unknown
    PresentationCore.dll!System.Windows.Input.CommandManager.FindCommandBinding(System.Windows.Input.CommandBindingCollection commandBindings, object sender, System.Windows.RoutedEventArgs e, System.Windows.Input.ICommand command, bool execute)    Unknown
    PresentationCore.dll!System.Windows.Input.CommandManager.FindCommandBinding(object sender, System.Windows.RoutedEventArgs e, System.Windows.Input.ICommand command, bool execute)   Unknown
    PresentationCore.dll!System.Windows.Input.CommandManager.OnExecuted(object sender, System.Windows.Input.ExecutedRoutedEventArgs e)  Unknown
    PresentationCore.dll!System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate handler, object target)   Unknown
    PresentationCore.dll!System.Windows.RoutedEventHandlerInfo.InvokeHandler(object target, System.Windows.RoutedEventArgs routedEventArgs) Unknown
    PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised)    Unknown
    PresentationCore.dll!System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args)   Unknown
    PresentationCore.dll!System.Windows.Input.RoutedCommand.ExecuteImpl(object parameter, System.Windows.IInputElement target, bool userInitiated)  Unknown
    PresentationCore.dll!System.Windows.Input.CommandManager.TransferEvent(System.Windows.IInputElement newSource, System.Windows.Input.ExecutedRoutedEventArgs e)  Unknown
    PresentationCore.dll!System.Windows.Input.CommandManager.OnExecuted(object sender, System.Windows.Input.ExecutedRoutedEventArgs e)  Unknown
    PresentationCore.dll!System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate handler, object target)   Unknown
    PresentationCore.dll!System.Windows.RoutedEventHandlerInfo.InvokeHandler(object target, System.Windows.RoutedEventArgs routedEventArgs) Unknown
    PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised)    Unknown
    PresentationCore.dll!System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args)   Unknown
    PresentationCore.dll!System.Windows.Input.RoutedCommand.ExecuteImpl(object parameter, System.Windows.IInputElement target, bool userInitiated)  Unknown
    PresentationFramework.dll!MS.Internal.Commands.CommandHelpers.CriticalExecuteCommandSource(System.Windows.Input.ICommandSource commandSource, bool userInitiated)   Unknown
    PresentationFramework.dll!System.Windows.Controls.Primitives.ButtonBase.OnClick()   Unknown
    PresentationFramework.dll!System.Windows.Controls.Button.OnClick()  Unknown
    System.Windows.Controls.Ribbon.dll!System.Windows.Controls.Ribbon.RibbonButton.OnClick()    Unknown
    PresentationFramework.dll!System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(System.Windows.Input.MouseButtonEventArgs e)    Unknown
    PresentationCore.dll!System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate handler, object target)   Unknown
    PresentationCore.dll!System.Windows.RoutedEventHandlerInfo.InvokeHandler(object target, System.Windows.RoutedEventArgs routedEventArgs) Unknown
    PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised)    Unknown
    PresentationCore.dll!System.Windows.UIElement.ReRaiseEventAs(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args, System.Windows.RoutedEvent newEvent)  Unknown
    PresentationCore.dll!System.Windows.UIElement.OnMouseUpThunk(object sender, System.Windows.Input.MouseButtonEventArgs e)    Unknown
    PresentationCore.dll!System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate handler, object target)   Unknown
    PresentationCore.dll!System.Windows.RoutedEventHandlerInfo.InvokeHandler(object target, System.Windows.RoutedEventArgs routedEventArgs) Unknown
    PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised)    Unknown
    PresentationCore.dll!System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args)   Unknown
    PresentationCore.dll!System.Windows.UIElement.RaiseTrustedEvent(System.Windows.RoutedEventArgs args)    Unknown
    PresentationCore.dll!System.Windows.Input.InputManager.ProcessStagingArea() Unknown
    PresentationCore.dll!System.Windows.Input.InputManager.ProcessInput(System.Windows.Input.InputEventArgs input)  Unknown
    PresentationCore.dll!System.Windows.Input.InputProviderSite.ReportInput(System.Windows.Input.InputReport inputReport)   Unknown
    PresentationCore.dll!System.Windows.Interop.HwndMouseInputProvider.ReportInput(System.IntPtr hwnd, System.Windows.Input.InputMode mode, int timestamp, System.Windows.Input.RawMouseActions actions, int x, int y, int wheel)   Unknown
    PresentationCore.dll!System.Windows.Interop.HwndMouseInputProvider.FilterMessage(System.IntPtr hwnd, MS.Internal.Interop.WindowMessage msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled)   Unknown
    PresentationCore.dll!System.Windows.Interop.HwndSource.InputFilterMessage(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled)    Unknown
    WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Unknown
    WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o) Unknown
    WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs)  Unknown
    WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler) Unknown
    WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs)   Unknown
    WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam)  Unknown
    [Native to Managed Transition]  
    [Managed to Native Transition]  
    WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame)   Unknown
    PresentationFramework.dll!System.Windows.Application.RunDispatcher(object ignore)   Unknown
    PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window)  Unknown


8 commentaires

Est ventes un tas par hasard?


1) Quelle instruction SQL utilisez-vous de SSMS? 2) Si vous exécutez la même déclaration du code, que se passe-t-il? 3) Si vous exécutez l'instruction SQL via une classe de base dBContext, que se passe-t-il?


@Alwayslearning: Je ne suis pas sûr de ce que vous entendez par un tas. Les ventes sont à peu près une table standard dans la base de données. C'est la table des parents pour la venteProduits.


@Zevspitz: La déclaration SQL que j'ai postée dans assez clairement. Je vais essayer d'exécuter la déclaration via SQLCLIENT et de faire rapport.


1. L'instruction SQL contient des paramètres; Comment les remplissez-vous pour SSMS? 2 .. Je suppose Ce est ce que le toujours enroulez-vous.


Pour tout ce qui prend aussi longtemps, recherchez le blocage et l'ouverture des transactions sur SQL Server.


@Alwayslearning: Bonjour. Merci d'avoir chippé. Les deux tables ont des clés principales en cluster. Donc, je suppose que ni ne seront considérés comme des tas


Bonjour @ Davidbrown-Microsoft, merci pour votre contribution. sys.processes ne montre aucune transaction ouverte. Que puis-je vérifier d'autre?


3 Réponses :


1
votes

La réponse spécifique à ce problème nécessitera de voir le code spécifique responsable. Ce n'est probablement pas un problème avec une seule table au-delà des relations que le tableau a défini dans le schéma DBContext et de base de données, ainsi que l'état actuel de ce que le DBContext suive. (Et quelle base de données peut être verrouillée, cependant, c'est généralement un type de problème plus intermittent)

Certaines choses à vérifier: Dans votre exemple d'application, vous semblez avoir une nouvelle instance de DBContext et de le disposer. (Good) Le 11 est-il de la 11ème fois reflète la recherche + sauvegarder ou simplement enregistrer? La toute première interrogation selon laquelle un dBContext exécute dans une application entraîne un coût de retournement 1-off (Static Static) pour initialiser le modèle. Pour un moment plus précis avec un scénario de premier point, vous pouvez faire quelque chose comme: xxx

* désolé, mon vb.net est malheureusement obsolète. :) dans n'importe quel Cas, en utilisant une opération rapide contre le dbcontext comme un tout () entraînera le coût de rotation 1-off. Toute opération après cela devrait être une représentation plus pure du temps nécessaire pour charger et enregistrer des données.

dans votre code problématique, est la garantie de DBContext pour être de courte durée? Les dBcontextes vivants accumulent de plus en plus de références à un certain nombre d'entités et à tout moment une entité est persistée, elle s'efforcera de déterminer l'arborescence d'entités de déterminer si des personnes connexes devraient être mises à jour. Les DBContexts de courte durée de vie sont la voie à suivre.

Avez-vous exécuté un profileur contre la base de données pour capturer le SQL Exact? Votre exemple SQL ne ressemble pas à une requête EF et fait référence à une table "Sales" plutôt que "SalesProduct". Avoir un profileur fonctionnant lors du débogage de vos opérations d'application EF est inestimable pour révéler des choses dans les coulisses que vous ne vous attendez pas.

Autres possibilités dépendrait vraiment du code en question, mais un profileur combiné avec Les points d'arrêt aideront généralement les problèmes de points. Le retard est-il confirmé pour être juste lorsque DBContext.Savechanges se produit, ou le processus d'enregistrement entier? Si c'est quelque chose comme à partir du moment où l'utilisateur clique sur un bouton Enregistrer, un profileur peut révéler que votre code déclenche beaucoup d'appels de chargement paresseux (chargement de données pour vérifier et mettre à jour avant de sauvegarder) ou charger des données inattendues. (Les problèmes courants que j'ai vus sont mal placés tolistes () appels avant de filtrer les instructions, généralement parce que les Devs veulent faire quelque chose que EF ne peut pas traduire et tolist () semble être un "Correction") Si le délai est juste des SAVECHANGES, le profileur peut confirmer quelles instructions de mise à jour et quelles sont produites et quelle durée ils prennent pour courir.


7 commentaires

Oh Wow @ Steve-Py, merci pour toutes ces informations. Je vais passer en revue la pièce par pièce et voir ce que je peux trouver une étape. Les 11 secondes sont la sauvegarde seulement. La recherche est peut-être une autre seconde environ. Toute la fonction prend peut-être 12 secondes. Jolie non pertinente. Notre vrai problème est quand il faut 5 minutes plus.


Dans le code problématique, le contexte n'est pas considéré comme de courte durée. Le point ici est de charger une entité, de se lier aux commandes de Windows, demandez à l'utilisateur de faire ses modifications nécessaires et d'enregistrer. Bien que pour tester, je peux ouvrir la fenêtre + modifier + appuyez sur Enregistrer dans environ 3 secondes. Et la question sera toujours persistante.


En ce qui concerne des entités supplémentaires, j'ai vérifié le Changetracker , et il n'y a pas d'entités supplémentaires. Juste le 2 qui doivent être là (vente du produit et sa vente parent). Lorsqu'un utilisateur met à jour un produit de vente, j'ai défini un actif = maintenant sur la vente elle-même. Ainsi, ef met également à jour la table de vente en même temps


J'ai posté une trace ici Pastebin.com/enlge0ln . Je ne vois rien de majeur. Mais j'aimerais entendre ce que vous voyez là-bas. Merci!


Pour profilage, vous pouvez utiliser SSMS Tools \ SQL Profiler ou une application comme Express Profiler. De là, définissez un point d'arrêt dans votre application, effacez le journal du profil, puis capturez ce qui se passe pendant la sauvegarde. Il est utile de le faire sur une copie de base de données qui n'a rien d'autre qui s'exprime pour réduire le bruit d'autres copies de l'application. À partir de la trace que vous avez fournie, il semble avoir fait plusieurs lectures et 1 mise à jour contre la vente dans la portée de 44 secondes. Je n'ai pas vu de mise à jour sur la venteProduite.


Salut. J'ai ajouté une nouvelle trace ici Paste.ee/P/siys6 . Ceci a été capturé à partir du point d'arrêt SAVECHANGES jusqu'à quelques minutes. Je n'ai pas attendu jusqu'à ce que cela prendrait 5 minutes plus et sauterait le fichier de trace. Mais je ne vois aucune référence à la table des ventes. J'ai peut-être manqué un événement important dans la trace? Quels événements sont importants pour ce problème?


Je ne pense pas que cette trace va aider beaucoup parce que cela semble être exécuté sur un serveur de base de données qui fait déjà un peu. Pour suivre les problèmes de performance, vous devez vraiment le configurer dans un environnement isolé avec rien d'autre en cours d'exécution contre la base de données. De là, un résultat du profileur (capturer le SQL et le temps de fonctionnement) suffit. Si sur une base de données isolée, rien d'autre, vous voyez un retard, il s'agit d'examiner le SQL en cours d'exécution pendant la sauvegarde. S'il est plus rapide de manière isolée, vous avez probablement beaucoup de blocage de LoadCommé partout.



-2
votes

Frame-entité est lent, très lent Dans le code de production, vous devez utiliser la commande C # SQL


0 commentaires

0
votes

En fin de compte, il semble que l'erreur a disparu après une reconstruction d'index. Même si je ne peux pas comprendre s'il s'agissait d'un problème d'index, comment se fait-il que cela a fonctionné sans faille et à nouveau via SSMS et EF sans fenêtre. Mais pour l'instant son travail juste dandy. Merci encore pour toutes les affiches, car vous étiez extrêmement utile pour réduire et se concentrer.


0 commentaires