我的SQL代码从列表中向表中插入10000条记录。若记录已经存在,它会更新一些字段。
目前它需要超过10分钟,除非我限制要处理的记录数量,否则会超时。我的代码中有什么可以解决这个问题的吗。
foreach(RMSResponse rmsObj in rmsList) {
try {
string connectionString = @"server=localhostsqlexpress;" + "Trusted_Connection=yes;" + "database=MyDB; " + "connection timeout=30";
SqlConnection conn = new SqlConnection(connectionString);
conn.Open();
string str = "";
str += "SELECT * ";
str += "FROM RMSResponse ";
str += "WHERE LeadID = @RecruitID";
int LeadID;
Boolean IsPositive = true;
SqlCommand selectCommand = new SqlCommand(str, conn);
selectCommand.CommandType = CommandType.Text;
selectCommand.Parameters.Add(new SqlParameter("@RecruitID", rmsObj.RecruitID));
SqlDataReader sqlDataReader = selectCommand.ExecuteReader();
bool hasRows = sqlDataReader.HasRows;
while (sqlDataReader.Read()) {
LeadID = sqlDataReader.GetInt32(1);
IsPositive = sqlDataReader.GetBoolean(2);
IsPositive = (IsPositive == true) ? false : true;
Console.WriteLine("Lead ID: " + LeadID + " IsPositive: " + IsPositive);
}
sqlDataReader.Close();
if (hasRows) {
SqlCommand updateCommand = new SqlCommand("UPDATE RMSResponse set IsPositive=@IsPositive, OptOutDate=@OptOutDate where LeadID=@LeadID", conn);
updateCommand.Parameters.AddWithValue("@LeadID", rmsObj.RecruitID);
updateCommand.Parameters.AddWithValue("@IsPositive", IsPositive);
updateCommand.Parameters.AddWithValue("@OptOutDate", DateTime.Now);
updateCommand.ExecuteNonQuery();
sqlDataReader.Close();
}
if (!hasRows) {
SqlCommand insertCommand = new SqlCommand("INSERT INTO RMSResponse (LeadID, IsPositive, ReceivedDate) " + "VALUES(@LeadID, @IsPositive, @ReceivedDate)", conn);
insertCommand.Parameters.AddWithValue("@LeadID", rmsObj.RecruitID);
insertCommand.Parameters.AddWithValue("@IsPositive", true);
insertCommand.Parameters.AddWithValue("@ReceivedDate", DateTime.Now);
int rows = insertCommand.ExecuteNonQuery();
}
} catch (SqlException ex) {
Console.WriteLine(ex.Message);
}
}
您可以将更新移动到SQL,只需将OptOutDate设置为今天即可。您可以将潜在客户ID列表传递给批处理更新语句。
要插入记录,可以大容量插入到临时表中,然后执行SQL来插入表中不存在的ID的数据。
C#中没有太多逻辑,所以先取出数据,然后再放回数据会使它变得不必要地慢。
如果你不想走下这个根,那么其他提示包括:
- 打开回路外的一个连接
- 在循环之外创建一个SqlCommand对象,并通过重置参数重新使用它
- 将select SQL更改为只选择需要的列,而不选择*
一个简单的更新或插入语句永远不应该花费10分钟。
SqlServer是一个非常好的数据库。
在表RMSResponse的LeadID上创建索引。
如果您的foreach在许多记录上循环,那么一定要考虑一个存储过程,存储过程会减少很多时间。
如果要更新或插入(UPSERT),请查看SqlServer 2008中添加的"合并"命令。