我试图弄清楚为什么存储过程调用在SQL Server express查询窗口中需要几秒钟,但是当我运行时,在代码中调用存储过程查询TIMES OUT。我们正在使用sql server 2008.我知道很难在没有看到存储过程的情况下确切地说明发生了什么。我只是希望这是一个已知的问题。非常感谢任何指导。
调用“STORED_PROCEDURE_X”并在SQL Server express查询窗口中运行2秒的SQL查询:
EXEC STORED_PROCEDURE_X '07/01/2010', '07/31/2010', 0, '', 'true','', 'Top 20'
调用“STORED_PROCEDURE_X”和TIMES OUT的代码:
SqlConnection connSQL = null;
SqlCommand sqlCmd = null;
SqlDataAdapter sqlDataAdpater = null;
DataTable returnData = null;
try
{
returnData = new DataTable();
connSQL = new SqlConnection(sqlConnection);
sqlCmd = new SqlCommand("STORED_PROC_X", connSQL);
if (connSQL.State == ConnectionState.Closed)
{
connSQL.Open();
}
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlCmd.CommandTimeout = 600;
sqlCmd.Parameters.Add("@StartDate", SqlDbType.NVarChar).Value = "07/01/2010";
sqlCmd.Parameters.Add("@EndDate", SqlDbType.NVarChar).Value = "07/31/2010";
sqlCmd.Parameters.Add("@AuditType", SqlDbType.Int).Value = "0";
sqlCmd.Parameters.Add("@SortBy", SqlDbType.NVarChar).Value = "";
sqlCmd.Parameters.Add("@IsClaimDepartment", SqlDbType.NVarChar).Value = "true";
sqlCmd.Parameters.Add("@IdsList", SqlDbType.NVarChar).Value = "";
sqlCmd.Parameters.Add("@ReportType", SqlDbType.NVarChar).Value = "Top 20";
sqlDataAdpater = new SqlDataAdapter(sqlCmd);
sqlDataAdpater.Fill(returnData);
if (connSQL.State == ConnectionState.Open)
{
connSQL.Close();
}
return returnData;
}
catch (Exception ex)
{
LogErrorMessages("ExecuteStoredProcedure", ex.Message);
throw ex;
}
收到异常:
System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
答案 0 :(得分:10)
所以,运行一个返回30条记录的存储过程在管理控制台中花了我00:00秒,但是当它加载到.net时花了我大约40秒,超过了默认的30秒TimeOut。
我只修改存储过程并重新运行ALTER PROCEDURE
...代码而不更改任何内容,问题立即得到解决。我没有关于此错误来源的更多详细信息,但至少它是一个非常快速的解决方案
答案 1 :(得分:4)
对我来说总是很有帮助的是在程序中添加“ with recompile ”选项。
答案 2 :(得分:3)
假设您在代码中传递与在SSMS中测试时相同的参数,并且您的SSMS测试在数据类型使用方面完全相同,我认为这可能是参数嗅探问题。
您是否可以访问SQL Profiler(不附带Express版本)来获取实际的执行计划?如果没有,您可以按照in this answer的建议来制定计划。
答案 3 :(得分:2)
我遇到类似的问题,存储过程比查询窗口中的同一查询运行得慢。 我已经尝试了编码参数嗅探(局部变量),删除聚簇索引和仅使用非聚集等等所有内容。使用nvarchar参数检索varchar字段仍需要22秒。
我原本以为只是nvarchar和varchar之间的区别,并将数据库字段更改为nvarchar。我又丢了一整天,将5000万条记录转移到新表并重新编制索引。仍然花了超过22秒。
最后,我将表中的任何关键字段从nvarchar更改为varchar,加上所有参数和哇;回到不到1秒。
我坚信这是SQL Server中的一个错误,从未得到纠正。如何直接在查询窗口中运行查询,或者从vb.net或c#代码调用sql并在不到1秒的时间内获得结果;然后在存储过程中使用参数运行相同的查询并得到这样的horrendus结果?
简短回答:不惜一切代价远离nvarchar数据类型。
另外,学习使用merge语句将数据移动到大表中以避免超时。 将恢复模式设置为简单,同时运行大型合并查询;然后恢复完全恢复。
男孩,本周我学到了很多东西。超过80小时的教育,我不需要。 但是,LinkToMeet.com现在有超过1.5亿会员,一切都很好。
答案 4 :(得分:1)
尝试a)重新组织代码,b)增加超时时间:
DataTable returnData = null;
try
{
using(SqlConnection connSQL = new SqlConnection(sqlConnection))
using(SqlCommand sqlCmd = new SqlCommand("STORED_PROC_X", connSQL))
{
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlCmd.CommandTimeout = 1200;
// those two parameters should really be SqlDbType.DateTime!!
sqlCmd.Parameters.Add("@StartDate", SqlDbType.NVarChar, 25).Value = "07/01/2010";
sqlCmd.Parameters.Add("@EndDate", SqlDbType.NVarChar, 25).Value = "07/31/2010";
sqlCmd.Parameters.Add("@AuditType", SqlDbType.Int).Value = "0";
sqlCmd.Parameters.Add("@SortBy", SqlDbType.NVarChar, 50).Value = "";
// this parameter should really be SqlDbType.Bit !!
sqlCmd.Parameters.Add("@IsClaimDepartment", SqlDbType.NVarChar, 50).Value = "true";
sqlCmd.Parameters.Add("@IdsList", SqlDbType.NVarChar, 25).Value = "";
sqlCmd.Parameters.Add("@ReportType", SqlDbType.NVarChar, 25).Value = "Top 20";
SqlDataAdapter sqlDataAdpater = new SqlDataAdapter(sqlCmd);
returnData = new DataTable();
sqlDataAdpater.Fill(returnData);
}
return returnData;
}
catch (Exception ex)
{
LogErrorMessages("ExecuteStoredProcedure", ex.Message);
throw;
}
SqlDataAdapter
将打开和关闭连接本身 - 无需明确地执行此操作。
此外,我会
throw
而不是throw ex
(如果你使用throw ex
,你基本上打破了堆栈跟踪,无法弄清楚异常的位置真的来自)答案 5 :(得分:1)
确保传递给SP的参数与数据库中的参数匹配[这是区分大小写]
答案 6 :(得分:0)
您是否在存储过程中使用任何事务?未提交的事务将导致此确切的错误消息。
答案 7 :(得分:0)
I had same issue. My stored proc executed from MSSMS or dbForgeStudio, but not from C# code (SqlCommand). I fixed this problem by altering stored proc in SQL server (without any changes).
答案 8 :(得分:0)
我尝试使用“ with recompile”,“ arithabort off”,更改代码等,但最后仅重新启动sql server即可解决问题。
答案 9 :(得分:0)
我们遇到了同样的问题,并认为它也是参数嗅探,但是在尝试了许多事情之后,包括更改参数嗅探,与重新编译一起使用,删除/重新创建,更新统计信息,释放proc缓存,我们发现这些都不起作用。我们将其跟踪到需要添加的单个索引。我们刚刚从传统基数估算器切换到2014年后估算器。切换回旧的估算器可以解决此问题,或者使用新的估算器并添加索引。
答案 10 :(得分:-1)
更改CommandTimeout = 0
sqlCmd.CommandTimeout = 0;