存储过程导致提取大型数据时连接时间执行错误



我正在调用SQL Server存储过程以从数据库中获取大量记录,但它在运行时会导致超时执行错误。我们怎样才能以这种方式使其快速?

我在实体框架中使用存储过程调用。存储过程采用输入参数,out参数是表中的总记录,用于前面的分页。我想获取每页 10 条记录的所有数据。数据库表名Player_account_flow,存储和存储过程名也被给出。我在数据加载时映射我的数据库模型。

using (SqlConnection conn = dbContext.Database.GetDbConnection() as SqlConnection)
{
conn.Open();                    
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = conn;
cmd.CommandText = "Pro_GetPageData"; 
cmd.CommandType = CommandType.StoredProcedure; 
// input parameters to procedure
cmd.Parameters.AddWithValue("@TableName", "Player_Account_Flow"); 
cmd.Parameters.AddWithValue("@OrderString", "Create_Time Desc"); 
cmd.Parameters.AddWithValue("@ReFieldsStr", "*");
cmd.Parameters.AddWithValue("@PageIndex", 1); 
cmd.Parameters.AddWithValue("@PageSize", 10); 
cmd.Parameters.AddWithValue("@WhereString", query);                                        
cmd.Parameters.AddWithValue("@TotalRecord", SqlDbType.Int); 
cmd.Parameters["@TotalRecord"].Direction = ParameterDirection.Output; 
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var map = new PlayerAccountFlow();
map.Id = (Int32)reader["Id"];
map.AccountId = (Int32)reader["AccountId"];
map.Type = (byte)reader["Type"];
map.BeforeAmout = (decimal)reader["BeforeAmout"];
map.AfterAmout = (decimal)reader["AfterAmout"];
map.Amout = (decimal)reader["Amout"];
map.Source = (Int32)reader["Source"];
map.Memo = reader["Memo"].ToString();                            
map.CreateTime = (DateTime)reader["Create_Time"];
playerAccountFlowsList.Add(map);
}
}
obj = cmd.Parameters["@TotalRecord"].Value;
}
}
PagingData<PlayerAccountFlow> pagingData = new PagingData<PlayerAccountFlow>();
pagingData.Countnum = (Int32)obj;
pagingData.Data = playerAccountFlowsList;
return pagingData;

这里有很多事情需要研究。您可以设置比默认值更长的命令超时。您可以查看存储过程,了解为什么它运行得如此缓慢。

对于命令超时,只需给它一个以秒为单位的值。在下面的示例中,这将是 2 分钟。尽管让他们等待几分钟来显示结果将是一种糟糕的用户体验。我建议首先优化存储过程(查看索引、多个连接、子查询等(。另外,您实际上是在用户界面上显示巨大的数据集,还是将其拆分为页面?可以将存储过程更改为仅返回当前页,并在用户转到下一页时再次调用它。编写良好的存储过程在仅返回整个数据的一小部分时应该会快得多。

using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = conn;
cmd.CommandTimeout = 120;
cmd.CommandText = "Pro_GetPageData"; 
cmd.CommandType = CommandType.StoredProcedure; 

在这种情况下,应重新访问存储过程,例如多个联接。您还应该问问自己是否应该立即加载所有数据。我建议显示初始数据并根据用户请求加载更多数据。这意味着您可以对数据库使用简单计数并根据结果计算页面,然后仅从选定范围内获取数据。

最新更新