我有一个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<BatchItem> data = new List<BatchItem>();
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();
}
答案 0 :(得分:2)
可能会发生各种各样的事情。
首先,Ivan G.是正确的,SSMS和ASP.NET客户端之间的连接参数和SET选项可能不同。如果您可以访问它,那么这在Profiler中值得关注。
其次,如果您在SSMS中连续多次运行查询,则可能会缓存结果,这就是SSMS中运行速度如此之快的原因。如果它在第一次打开SSMS并尝试运行它时运行缓慢,但随后加速,这就是缓存正在进行的迹象。
至于为什么在连接中添加一个额外的子句可以减慢速度,很难说如果不了解更多关于你的表的原因,但这并不是不可能的。是否有BATCH_INGR
的索引包括FACTORY
和INGR_CODE
?您现在可能需要一个在加入条件中包含INGR_CODE
的人。
找出的最佳方法是查看带有和不带INGR_CODE
子句的查询计划,看看它有何不同。一个查询的成本数字是否大于另一个查询的成本数字?是否有以前没有的表扫描?索引搜索变成了索引扫描吗?
答案 1 :(得分:2)
我以前不得不麻烦拍摄这些,但它们并不好玩,但根据我的经验,我所看到的是ASP.NET和它之间的不同执行计划。在SSMS中运行查询。 ASP.NET不会缓存查询,SSMS会这样做,但有时执行计划实际上是不同的。罪魁祸首经常是一个不按顺序访问的坏索引,这是我倾向于使用的指南:
答案 2 :(得分:1)
这是因为查询计划缓存不一样。
这是因为您的代码和SSMS不使用相同的设置,并且因为参数欺骗(即Sql Server根据第一次sp执行和您此次发送的参数创建计划缓存)=&gt;当您通过代码和SSMS执行时,您没有相同的查询执行计划。
确保您使用的是同一计划:工具 - &gt;查询执行 - &gt; SQL Server - &gt;进展 - &gt;取消选中“SET ARITHABORT”
答案 3 :(得分:-1)
避免在您提到的stroredprocedure中调用另一个存储过程。这将解决您的问题