在SSMS中运行良好的SQL查询在ASP.NET中运行速度非常慢

我有一个asp.net页面加载一个我们知道从SQL Server Management Studio执行时运行正常(在1到2秒内)的查询,但是当在SQLCommand中从ASP.NET执行时,查询需要的时间要长得多,我不能似乎弄清楚除了自问题开始以来已经添加到查询中的一行以外发生了什么,但我找不到问题所在。

添加的有问题的代码行是第6行: bi.INGR_CODE != 0

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 

ASP.NET代码文件背后

 //Temporary List List data = new List(); string SQLCommand = DBHelper.LoadSQLStatement( "batchdescription.sql" ); System.Data.SqlClient.SqlConnection sqlConnection = new System.Data.SqlClient.SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionStringNameReplaced"].ConnectionString); 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].ToString(), Description = DataReader[1].ToString(), Total = decimal.Parse( DataReader[2].ToString() ) } ); } } catch ( Exception ex ) { //handle exceptions } finally { sqlConnection.Close(); } 

有各种各样的事情可以发生。

首先,Ivan G.是正确的,SSMS和ASP.NET客户端之间的连接参数和SET选项可能不同。 如果您有权访问它,那么这在Profiler中值得关注。

其次,如果您在SSMS中连续多次运行查询,则可能会缓存结果,这就是SSMS中运行速度如此之快的原因。 如果它在第一次打开SSMS并尝试运行它时运行缓慢,但随后加速,这就是缓存正在进行的迹象。

至于为什么在连接中添加一个额外的子句会减慢速度,很难说如何在不了解更多关于表的情况下解决原因,但这并不是不可能的。 BATCH_INGR上是否有一个包含FACTORYINGR_CODE ? 您现在可能需要一个在连接条件中包含INGR_CODE

找出的最佳方法是查看带有和不带INGR_CODE子句的查询计划,看看它有何不同。 一个查询的成本数字是否大于另一个查询的成本数字? 是否有以前没有的表扫描? 索引搜索变成了索引扫描吗?

我以前不得不麻烦拍摄这些,但它们并不好玩,但根据我的经验,我看到的是ASP.NET与SSMS中运行查询之间的不同执行计划。 ASP.NET不会缓存查询,SSMS会这样做,但有时执行计划实际上是不同的。 罪魁祸首经常是一个不按顺序访问的坏索引,这里是我倾向于使用的指南:

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

这是因为查询计划缓存不一样。

这是因为您的代码和SSMS不使用相同的设置,并且因为参数欺骗(即Sql Server根据第一次sp执行创建计划缓存以及此次发送的参数)=>当您通过代码执行并通过SSMS执行时您没有相同的查询执行计划。

为了确保您使用相同的计划:工具 – >查询执行 – > SQL Server – >高级 – >取消选中“SET ARITHABORT”

避免在您提到的stroredprocedure中调用另一个存储过程。 这将解决您的问题