我有一个包含大约8000条记录的datagridview,对于每条记录,我调用一个SQL Server存储过程将其插入到数据库中,代码如下:
for (int i = 0; i < dgv_compare.Rows.Count; i++)
{
if (!DBCommands.sp_app_RatePlanDetail_Add(
CarrierID,
is_supplier == 1 ? 0 : 1,
row.Prefix,
row.RegionName,
row.NewRate,
row.FreeBlock,
row.InitialBlock,
row.RecycleBlock,
row.ConnectionCharge,
row.EnrollDate,
row.ExpiryDate,
row.isDisabled,
row.TimeF1,
row.TimeT1,
row.Rate1,
row.Block1Enabled,
row.TimeF2,
row.TimeT2,
row.Rate2,
row.Block2Enabled,
row.TimeF3,
row.TimeT3,
row.Rate3,
row.Block3Enabled,
Operator,
FlagShortOverLong,
ref ErrCode,
ref ErrMsg))
{
//tb_log.Text += DBCommands.LastError + "\r\n";
MessageBox.Show(DBCommands.LastError);
return;
}
}
函数DBCommands.sp_app_RatePlanDetail_Add
就是这种形式:
public static bool sp_app_RatePlanDetail_Add
(
int CustID,
int IsInBound,
string Prefix,
string RegionName,
double RatePerMin,
int FreeBlock,
int InitialBlock,
int RecycleBlock,
double ConnectionCharge,
DateTime EnrollDate,
DateTime ExpiryDate,
int isDisabled,
TimeSpan TimeF1,
TimeSpan TimeT1,
double Rate1,
int Block1Enabled,
TimeSpan TimeF2,
TimeSpan TimeT2,
double Rate2,
int Block2Enabled,
TimeSpan TimeF3,
TimeSpan TimeT3,
double Rate3,
int Block3Enabled,
string Operator,
int FlagShortOverLong,
ref int ErrCode,
ref string ErrMsg
)
{
SqlConnection conn = null;
SqlCommand sqlCmd = null;
try
{
try
{
conn = new SqlConnection(ConnectString);
conn.Open();
if (conn.State != ConnectionState.Open)
{
LastErrorCode = -1;
LastError = "Connect database error.";
return false;
}
}
catch (Exception ex)
{
LastErrorCode = -1;
LastError = "Connect database error. " + ex.ToString();
return false;
}
try
{
sqlCmd = new SqlCommand("sp_app_RatePlanDetail_Add_0909", conn);
sqlCmd.CommandTimeout = ExecuteTimeout;
sqlCmd.CommandType = CommandType.StoredProcedure;
AddParam(sqlCmd, "@CustID", SqlDbType.Int, 4, 10, 0, ParameterDirection.Input, CustID);
AddParam(sqlCmd, "@IsInBound", SqlDbType.Int, 4, 10, 0, ParameterDirection.Input, IsInBound);
AddParam(sqlCmd, "@Prefix", SqlDbType.VarChar, 60, 30, 0, ParameterDirection.Input, Prefix);
AddParam(sqlCmd, "@RegionName", SqlDbType.VarChar, 400, 200, 0, ParameterDirection.Input, RegionName);
AddParam(sqlCmd, "@RatePerMin", SqlDbType.Decimal, 13, 20, 10, ParameterDirection.Input, RatePerMin);
AddParam(sqlCmd, "@FreeBlock", SqlDbType.Int, 4, 10, 0, ParameterDirection.Input, FreeBlock);
AddParam(sqlCmd, "@InitialBlock", SqlDbType.Int, 4, 10, 0, ParameterDirection.Input, InitialBlock);
AddParam(sqlCmd, "@RecycleBlock", SqlDbType.Int, 4, 10, 0, ParameterDirection.Input, RecycleBlock);
AddParam(sqlCmd, "@ConnectionCharge", SqlDbType.Decimal, 9, 18, 8, ParameterDirection.Input, ConnectionCharge);
AddParam(sqlCmd, "@EnrollDate", SqlDbType.DateTime, 8, 23, 3, ParameterDirection.Input, EnrollDate);
AddParam(sqlCmd, "@ExpiryDate", SqlDbType.DateTime, 8, 23, 3, ParameterDirection.Input, ExpiryDate);
AddParam(sqlCmd, "@isDisabled", SqlDbType.Int, 4, 10, 0, ParameterDirection.Input, isDisabled);
AddParam(sqlCmd, "@TimeF1", SqlDbType.Time, 5, 16, 7, ParameterDirection.Input, TimeF1);
AddParam(sqlCmd, "@TimeT1", SqlDbType.Time, 5, 16, 7, ParameterDirection.Input, TimeT1);
AddParam(sqlCmd, "@Rate1", SqlDbType.Decimal, 13, 20, 10, ParameterDirection.Input, Rate1);
AddParam(sqlCmd, "@Block1Enabled", SqlDbType.Int, 4, 10, 0, ParameterDirection.Input, Block1Enabled);
AddParam(sqlCmd, "@TimeF2", SqlDbType.Time, 5, 16, 7, ParameterDirection.Input, TimeF2);
AddParam(sqlCmd, "@TimeT2", SqlDbType.Time, 5, 16, 7, ParameterDirection.Input, TimeT2);
AddParam(sqlCmd, "@Rate2", SqlDbType.Decimal, 13, 20, 10, ParameterDirection.Input, Rate2);
AddParam(sqlCmd, "@Block2Enabled", SqlDbType.Int, 4, 10, 0, ParameterDirection.Input, Block2Enabled);
AddParam(sqlCmd, "@TimeF3", SqlDbType.Time, 5, 16, 7, ParameterDirection.Input, TimeF3);
AddParam(sqlCmd, "@TimeT3", SqlDbType.Time, 5, 16, 7, ParameterDirection.Input, TimeT3);
AddParam(sqlCmd, "@Rate3", SqlDbType.Decimal, 13, 20, 10, ParameterDirection.Input, Rate3);
AddParam(sqlCmd, "@Block3Enabled", SqlDbType.Int, 4, 10, 0, ParameterDirection.Input, Block3Enabled);
AddParam(sqlCmd, "@Operator", SqlDbType.VarChar, 60, 30, 0, ParameterDirection.Input, Operator);
AddParam(sqlCmd, "@FlagShortOverLong", SqlDbType.Int, 4, 10, 0, ParameterDirection.Input, FlagShortOverLong);
AddParam(sqlCmd, "@ErrCode", SqlDbType.Int, 4, 10, 0, ParameterDirection.Output, null);
AddParam(sqlCmd, "@ErrMsg", SqlDbType.VarChar, 100, 50, 0, ParameterDirection.Output, null);
sqlCmd.Parameters.Add("@RETURN_VALUE", SqlDbType.Int, 4);
sqlCmd.Parameters["@RETURN_VALUE"].Direction = ParameterDirection.ReturnValue;
sqlCmd.ExecuteNonQuery();
ErrCode = get_int_value(sqlCmd.Parameters["@ErrCode"].Value);
ErrMsg = get_string_value(sqlCmd.Parameters["@ErrMsg"].Value);
int _temp = Convert.ToInt32(sqlCmd.Parameters["@RETURN_VALUE"].Value.ToString());
return true;
}
catch (Exception ex)
{
LastErrorCode = -1;
LastError = "Execute sp_app_RatePlanDetail_Add error. " + ex.ToString();
return false;
}
}
finally
{
if (sqlCmd != null)
sqlCmd.Dispose();
if (conn != null)
{
conn.Close();
conn.Dispose();
}
}
}
因为我需要做一些检查和比较,所以我无法将datagridview保存到csv并立即插入总数据集。
在这个程序sp_app_RatePlanDetail_Add_0909
中,我做了一些更新和删除,插入运算符,虽然它可以工作,但是花了太多时间
我认为这可能是因为unoptimize更新或删除,所以我尝试更改过程sp_app_RatePlanDetail_Add_0909
,让它只包含一个语句,如下所示:
select @a=1
但是很奇怪,整个程序的速度似乎根本没有变化,它仍然花费很多时间,任何人都可以告诉我是什么原因?感谢。
答案 0 :(得分:2)
我认为这可能是因为unoptimize更新或删除,所以我尝试更改过程
sp_app_RatePlanDetail_Add_0909
,让它只包含一个语句,如下所示:select @a=1
但是很奇怪,整个程序的速度似乎根本没有变化,它仍然花费很多时间,有人能告诉我是什么原因吗?感谢。
强调我的。
这表明您的问题与延迟有关(或者,存储过程的性能不性能问题;考虑寻找其他地方)。也就是说,发送执行存储过程的请求并接收结果的时间远远大于执行存储过程所花费的时间。
由于您每个记录调用一次存储过程,因延迟而“浪费”的时间会增加8,000倍。
您可以使用table valued parameters一次将多条记录流式传输到存储过程,从而显着减少往返次数。
请注意,使用表值参数不是灵丹妙药,由于参数嗅探,您的存储过程可能会遇到性能不佳。
答案 1 :(得分:0)
您确定存储过程执行时间过长吗?或者您指的是通过DataGridView执行整个循环?因为据我所知,你实际上是在打开和关闭数据库的8000个连接,这可能会耗费一些时间。
答案 2 :(得分:0)
似乎您为存储过程的每次调用打开/关闭连接。如果要提高性能,首先尝试使用单个连接而不是多个连接(即将连接作为参数传递给方法并在外部处理连接)。类似的东西:
using (SqlConnection con = new SqlConnection("your connection string")){
con.Open();
for (int i = 0; i < dgv_compare.Rows.Count; i++)
{
if (!DBCommands.sp_app_RatePlanDetail_Add(
con,
CarrierID,
...
};
con.Close();
}
相信这会缓解性能问题