Une requête SQL qui fonctionne correctement dans SSMS est très lente dans ASP.NET

J’ai une page asp.net qui charge une requête que nous soaps exécuter correctement (dans un délai de 1 à 2 secondes) lorsqu’elle est exécutée à partir de SQL Server Management Studio. Toutefois, lorsqu’elle est exécutée à partir d’ASP.NET dans une commande SQLC, la requête prend beaucoup plus de temps, je ne peux pas semble comprendre ce qui se passe autre qu’une ligne a été ajoutée à la requête depuis le début du problème, mais je ne parviens pas à localiser le problème.

La ligne de code incriminée qui a été ajoutée est la ligne 6: bi.INGR_CODE != 0

Instruction SQL

  SELECT bh.JOB_NUMBER, j.DESCRIPTION, SUM(bi.INGR_ACTUAL) AS TOTAL FROM BATCH_HEADER AS bh LEFT OUTER JOIN BATCH_INGR AS bi ON bh.BATCH_ID = bi.BATCH_ID AND bh.FACTORY = bi.FACTORY AND bi.INGR_CODE  0 LEFT OUTER JOIN ServerNameReplaced.man_prod.dbo.JOBS AS j ON bh.JOB_NUMBER = j.JOB_NUMBER COLLATE database_default AND bh.FACTORY = j.FACTORY COLLATE database_default WHERE ( bh.FACTORY = @Factory ) AND ( bh.DATETIME_DUMP >= @StartDate ) AND ( bh.DATETIME_DUMP < @EndDate ) GROUP BY bh.JOB_NUMBER, j.DESCRIPTION ORDER BY bh.JOB_NUMBER 

Code derrière fichier ASP.NET

 //Temporary List List data = new List(); ssortingng SQLCommand = DBHelper.LoadSQLStatement( "batchdescription.sql" ); System.Data.SqlClient.SqlConnection sqlConnection = new System.Data.SqlClient.SqlConnection(ConfigurationManager.ConnectionSsortingngs["ConnectionSsortingngNameReplaced"].ConnectionSsortingng); System.Data.SqlClient.SqlCommand sqlCommand = new System.Data.SqlClient.SqlCommand(SQLCommand, sqlConnection ); try { sqlCommand.Parameters.Add( "@StartDate", System.Data.SqlDbType.DateTime ).Value = StartDate; sqlCommand.Parameters.Add( "@EndDate ", System.Data.SqlDbType.DateTime ).Value = EndDate; sqlCommand.Parameters.Add( "@Factory", System.Data.SqlDbType.VarChar, 2 ).Value = Factory; sqlConnection.Open(); SqlDataReader DataReader = sqlCommand.ExecuteReader(); while ( DataReader.Read() ) { data.Add( new BatchItem() { JobNumber = DataReader[0].ToSsortingng(), Description = DataReader[1].ToSsortingng(), Total = decimal.Parse( DataReader[2].ToSsortingng() ) } ); } } catch ( Exception ex ) { //handle exceptions } finally { sqlConnection.Close(); } 

Il y a toutes sortes de choses qui pourraient se passer.

Tout d’abord, Ivan G. a raison de dire que les parameters de connexion et les options SET peuvent être différents entre SSMS et votre client ASP.NET. Cela vaut la peine de regarder dans Profiler, si vous y avez access.

Deuxièmement, si vous avez exécuté votre requête plusieurs fois de suite dans SSMS, il est possible que les résultats soient mis en cache, raison pour laquelle elle s’exécute si rapidement dans SSMS. S’il fonctionne lentement la première fois que vous ouvrez SSMS et essayez de l’exécuter, puis accélérez, c’est le signe que la mise en cache est en cours.

Quant à savoir pourquoi l’ajout d’une clause supplémentaire à une jointure pourrait ralentir les choses, il est difficile de dire pourquoi sans en savoir plus sur vos tables, mais il n’est pas impossible que cela aurait pu le faire. Existe-t-il un index sur BATCH_INGR incluant à la fois FACTORY et INGR_CODE ? Vous en aurez peut-être besoin maintenant que vous INGR_CODE dans vos conditions de jointure.

La meilleure façon de le savoir consiste à examiner le plan de requête avec et sans la clause INGR_CODE et à voir en quoi il diffère. Le coût d’une requête est-il supérieur à celui de l’autre? Y a-t-il des scans de table où il n’y en avait pas auparavant? Une recherche d’index est-elle devenue une parsing d’index?

J’ai déjà eu à résoudre ces problèmes auparavant, et ils ne sont pas amusants, mais d’après mon expérience, différents plans d’exécution ont été observés entre ASP.NET et l’exécution de la requête dans SSMS. ASP.NET ne met pas la requête en cache, contrairement à SSMS, mais le plan d’exécution est parfois différent. Le coupable est souvent un index erroné auquel on accède de manière erronée. Voici le guide que j’ai tendance à utiliser:

http://www.sommarskog.se/query-plan-mysteries.html

C’est parce que le cache du plan de requête n’est pas le même.

Cela est dû au fait que votre code et SSMS n’utilisent pas les mêmes parameters et en raison de l’usurpation de parameters (par exemple, Sql Server crée le cache de planification en fonction de la première exécution sp et des parameters que vous avez envoyés cette fois) => lorsque vous exécutez via code et via SSMS vous n’avez pas le même plan d’exécution de requête.

Pour vous assurer que vous utilisez le même plan: outil -> Exécution de la requête -> SQL Server -> Avancé -> décochez “SET ARITHABORT”

Évitez d’appeler une autre procédure stockée dans une procédure strored que vous avez mentionnée. Cela résoudra votre problème