2016-11-22 79 views
0

我想插入一些數據到兩個MYSQL表中。 第二個表將第一個錶行ID存儲爲外鍵。 我有這個代碼工作正常,但它超級慢。什麼是使其更快的最好/最快的方式?如何插入多個MYSQL表C#快?

string ConnectionString = "server=localhost; password = 1234; database = DB ; user = Jack"; 
     MySqlConnection mConnection = new MySqlConnection(ConnectionString); 
     mConnection.Open(); 
     int index = 1; 


     for (int i = 0; i < 100000; i++) 
     { 

      string insertPerson = "INSERT INTO myentities(Name) VALUES (@first_name);" 
        + "INSERT INTO secondtable(Id, Name,myentities) VALUES (@ID, @city, LAST_INSERT_ID());"; 
      MySqlCommand command = new MySqlCommand(insertPerson, mConnection); 
      command.Parameters.AddWithValue("@first_name", "Jack"); 
      command.Parameters.AddWithValue("@ID", i+1); 

      command.Parameters.AddWithValue("@city", "Frank"); 

      command.ExecuteNonQuery(); 
      command.Parameters.Clear(); 
     } 

我發現上的計算器問題之一下面的代碼,但它是將數據插入到一個表只,而不是應用,即通過外鍵連接的多個表。 這段代碼非常快,但我不確定如何使它能夠處理多個表。

public static void BulkToMySQL() 
{ 
    string ConnectionString = "server=192.168.1xxx"; 
    StringBuilder sCommand = new StringBuilder("INSERT INTO User (FirstName, LastName) VALUES ");   
    using (MySqlConnection mConnection = new MySqlConnection(ConnectionString)) 
    { 
     List<string> Rows = new List<string>(); 
     for (int i = 0; i < 100000; i++) 
     { 
      Rows.Add(string.Format("('{0}','{1}')", MySqlHelper.EscapeString("test"), MySqlHelper.EscapeString("test"))); 
     } 
     sCommand.Append(string.Join(",", Rows)); 
     sCommand.Append(";"); 
     mConnection.Open(); 
     using (MySqlCommand myCmd = new MySqlCommand(sCommand.ToString(), mConnection)) 
     { 
      myCmd.CommandType = CommandType.Text; 
      myCmd.ExecuteNonQuery(); 
     } 
    } 
} 
+0

你發現的代碼也是痛苦的不安全。它實際上是乞求被黑客攻擊。不要使用它。 –

回答

1

可能的最快的方法是制定一項戰略,通過.NET MySQL連接環沒有要求MySQL的。特別是對於i = 0到99999。您實現這一目標的方法是要麼通CASE答:直接db表操縱或案例B:通CSV到DB進口與LOAD DATA INFILE

對於CASE B:它往往是明智以使該數據轉換成一個臨時表或表。根據具體情況,可以檢查數據準備情況。這意味着您可能需要清理外部數據(ETL)。其他好處包括不會將不正確的數據提交給不適合消費的生產表。所以它會給你打開一個放棄選項。

現在轉向表現軼事。使用MySQL和2016年末的.NET Connector版本6.9.9.0,通過採用此路線,我可以實現高達40倍的性能提升。不調用INSERT查詢可能看起來不自然,但我不在循環中。好吧,當然,在小循環中,但不是數據攝入散裝。甚至沒有500行。如果您重新制作一些例程,您將體驗到明顯的UX改進。

因此,以上是針對真正來自外部的數據。對於CASE A:已經在您的數據庫中的上述正常數據不適用。在這些情況下,您儘可能在服務器端儘可能使用SQL來按摩數據(讀取率:100%)。因此,它不會將數據返回給客戶端,因此需要某些帶有Connector循環調用的客戶端將其返回到服務器。這不必強制執行存儲過程或根本不執行。客戶端調用操作數據,而不是客戶端傳輸,然後備份是您拍攝的內容。

0

您可以通過移動不必要的操作圈外獲得一些改善,因爲什麼,你在那裏做,重複10萬次:

string insertPerson = 
    "INSERT INTO myentities(Name) VALUES (@first_name);" 
    + "INSERT INTO secondtable(Id, Name,myentities) VALUES (@ID, @city, LAST_INSERT_ID());"; 
string ConnectionString = "server=localhost; password = 1234; database = DB ; user = Jack"; 

using (var Connection = new MySqlConnection(ConnectionString)) 
using (var command = new MySqlCommand(insertPerson, mConnection)) 
{ 
    //guessing at column types and lengths here 
    command.Parameters.Add("@first_name", MySqlDbType.VarChar, 50).Value = "Jack"; 
    var id = command.Parameters.Add("@ID", MySqlDbType.Int32); 
    command.Parameters.Add("@city", MySqlDbType.VarChar, 50).Value = "Frank"; 


    mConnection.Open(); 
    for (int i = 1; i <= 100000; i++) 
    { 
     id.Value = i; 
     command.ExecuteNonQuery(); 
    } 
} 

但總的來說,你嘗試避免這種情況。相反,您可以使用數字表格來預先投影兩個表格的結果。有some things you can do外鍵約束來設置鎖定(如果有人插入或嘗試讀取部分插入的記錄,則需要鎖定整個表以避免錯誤鍵),事務日誌記錄(您可以設置它只記錄批處理,而不是每個日誌更改)和外鍵強制(您可以在處理插入時將其關閉)。