简体   繁体   English

MySQL ExecuteNonQuery花费的时间太长

[英]MySQL ExecuteNonQuery takes too long

Maybe this is not the best source I've ever written but it is for a simple form that has the goal to write data remotely. 也许这不是我写过的最好的资料,但是它是针对以远程写入数据为目标的简单表单。 I've two MySQLConnections both for a local database. 我有两个MySQLConnections都用于本地数据库。 localconnection is used to read the DB and updateconnection edit every single row. localconnection用于读取数据库和updateconnection编辑每一行。 The problem is that when i'm trying to update the Database the program raise a timeout and it crash. 问题是,当我尝试更新数据库时,该程序引发超时并崩溃。 I think the problem is generated by the while loop . 我认为问题是由while循环引起的 My intention is to read a single row, post it on the server and update it if the server returns the status equals 200. 我的意图是读取一行,将其发布到服务器上,如果服务器返回的状态等于200,则对其进行更新。

Here's the code, it fails on updateConnection.ExcecuteNonQuery(); 这是代码,它在updateConnection.ExcecuteNonQuery();上失败。

    // Local Database here.
    localCommand.Parameters.Clear();
    // 0 - Grab unsent emails
    string receivedMessages = "SELECT * FROM EMAIL WHERE HASSENT = 0";
    // Update connection init START
    string updateConnectionString = "Server=" + this.localServer + ";Database=" + this.localDatabase + ";Uid=" + this.localUser + ";Pwd=" + this.localpassword;
    MySqlConnection updateConnection = new MySqlConnection(updateConnectionString);
    updateConnection.Open();
    MySqlTransaction transaction = updateConnection.BeginTransaction();
    MySqlCommand updateCommand = new MySqlCommand();
    // Update connection init END
    localCommand.Connection = localConnection;
    localCommand.Prepare();
    try
    {
      localCommand.CommandText = receivedMessages;
      MySqlDataReader reader = localCommand.ExecuteReader();
      while (reader.Read()) // Local db read
      {
       String EID = reader.GetString(0);
       String message = reader.GetString(3);
       String fromEmail = reader.GetString(6);
       String toEmail= reader.GetString(12);
       // 1 - Post Request via HttpWebRequest
       var receivedResponse = JObject.Parse(toSend.setIsReceived(fromEmail, message, toEmail));
       // 2 - Read the JSON response from the server
       if ((int)receivedResponse["status"] == 200)
       {
           string updateInbox = "UPDATE EMAIL SET HASSENT = 1 WHERE EMAILID = @EID";
           MySqlParameter EMAILID = new MySqlParameter("@EID", MySqlDbType.String);
           EMAILID.Value = EID; // We use the same fetched above
           updateCommand.Connection = updateConnection;
           updateCommand.Parameters.Add(IID_value);
           updateCommand.Prepare();
           updateCommand.CommandText = updateInbox;
           updateCommand.ExecuteNonQuery();
       }
       else
       {
          // Notice the error....
       }
     }
   }
   catch (MySqlException ex)
   {
     transaction.Rollback();
     // Notice...

   }
   finally
   {
     updateConnection.Close();
   }

It is hard to tell exactly what's wrong here without doing some experiments. 如果不做一些实验,就很难确切地说出问题所在。

There are two possibilities, though. 但是,有两种可能性。

First, your program appears to be running on a web server, which necessarily constrains it to run for a limited amount of time. 首先,您的程序似乎正在Web服务器上运行,这必然限制了它在有限的时间内运行。 But, you loop through a possibly large result set, and do stuff of an uncontrollable duration for each item in that result set. 但是,您遍历了一个可能很大的结果集,并对该结果集中的每个项目进行了持续时间无法控制的工作。

Second, you read a result set row by row from the MySQL server, and with a different connection try to update the tables behind that result set. 其次,您从MySQL服务器逐行读取结果集,并使用不同的连接尝试更新该结果集后面的表。 This may cause a deadlock, in which the MySQL server blocks one of your update queries until the select query completes, thus preventing the completion of the select query. 这可能会导致死锁,在该死锁中,MySQL服务器将阻止您的更新查询之一,直到选择查询完成,从而阻止选择查询完成。

How to cure this? 怎么治呢? First of all, try to handle a fixed and small number of rows in each invocation of this code. 首先,尝试在每次调用此代码时处理固定的少量行。 Change your select query to 将您的选择查询更改为

SELECT * FROM EMAIL WHERE HASSENT = 0 LIMIT 10

and you'll handle ten records each time through. 您每次将处理十条记录。

Second, read in the whole result set from the select query, into a data structure, then loop over the items. 其次,从选择查询中读取整个结果集,并将其读入数据结构,然后遍历各项。 In other words, don't nest the updates in the select. 换句话说,不要在选择中嵌套更新。

Third, reduce the amount of data you handle by changing SELECT * to SELECT field, field, field . 第三,通过将SELECT *更改为SELECT field, field, field来减少处理的数据量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM