2013-08-01 6 views
0

Мне нужно вставить 90Mb данных в таблицы MySql, и я использую команду INSERT IGNORE, чтобы избежать исключения дублирующего ключа. Производительность - 8 записей в секунду, но кажется очень медленной. Могу ли я поститься?MySql Insert Ignore performance

p.s. Я вставив запись для каждой записи, так как я читать данные из базы данных SQL Compact

using (SqlCeConnection sqlConnection = new SqlCeConnection(connectionstrCe)) 
      { 
       sqlConnection.Open(); 
       SqlCeCommand cmdCe = sqlConnection.CreateCommand(); 
       { 
        { 

         mySQLConnection.Open(); 

         foreach (KeyValuePair<string, List<string>> t in tablesCeNames) //reading the tables property from the dictionary - column names and datatypes 
         { 

          string tableData = t.Key; 
          List<string> columnData = t.Value; 
//get the values from the table I want to transfer the data 
           cmdText = "SELECT * FROM " + tableData; 
//compose the mysql command 
           cmdCe.CommandText = cmdText; 

           SqlCeDataReader dataReader = cmdCe.ExecuteReader(); //read 
//InsertTable is a method that get the datareader and convert all the data from this table in a list array with the values to insert 
           inputValues = InsertTables(dataReader); 


           MySql.Data.MySqlClient.MySqlTransaction transakcija; 
           transakcija = mySQLConnection.BeginTransaction(); 

           worker.ReportProgress(4, inputValues.Count); 

           foreach (string val in inputValues)//foreach row of values of the data table 
           { 
            cmdSqlText = "INSERT IGNORE INTO " + tableData + "("; //compose the command for sql 

            foreach (string cName in columnData) //forach column in a table 
            { 
             string[] data = cName.Split(' '); 
             if (!data[0].ToString().Equals("Id")) 
             { 
              cmdSqlText += data[0].ToString() + ","; //write the column names of the values that will be inserted 
             } 
            } 
            cmdSqlText = cmdSqlText.TrimEnd(','); 
            cmdSqlText += ") VALUES ("; 
//val contains the values of this current record that i want to insert 
            cmdSqlText += val; //final command with insert ignore and the values of one record 
            if (!val.Equals("")) 
            { 
             try 
             { 
              new MySql.Data.MySqlClient.MySqlCommand(cmdSqlText, mySQLConnection, transakcija).ExecuteNonQuery(); //execute insert on sql database 
              WriteToTxt("uspješno upisano u mysql" + t.Key); 
             } 
             catch (MySql.Data.MySqlClient.MySqlException sqlEx) 
             { 
             } 
            } 
           } 

           if (TablicaSveOK) 
           { 
            transakcija.Commit(); 

           } 
           else 
           { 
            transakcija.Rollback(); 
           } 
          } 
         } 

         if (mySQLConnection.State != System.Data.ConnectionState.Closed) 
         { 
          mySQLConnection.Close(); 
         } 
        } 
+1

Одним из способов было бы построить строку строитель в вашем цикле и сделать вставку снаружи ... это займет некоторое тепло от попадания в базу данных для каждой записи – Zaki

+0

@ Так вы хотите вставить группу записей на время? – user1788654

+0

Возможно, ваш код может быть отброшен много, но, не видя его ..... – Steve

ответ

0

Вместо того, отправка нескольких вызовов вы можете отправить один вызов для вставки всех записей. Вставьте его вот так:

insert into your table(col1, col2) 
SELECT 'Name1', 'Location1' 
UNION ALL 
SELECT 'Name2', 'Location2' 
UNION ALL 
SELECT 'Name3', 'Location3' 

Часть из этого возможно, что ваш код - это горловина бутылки, а не инструкция вставки. Поэтому я бы посоветовал вам сначала проверить, где лежит проблема, а затем пойти на решение.

0

Последний MySql.Connector имеет класс, называемый MySqlBulkLoader, который может использоваться для вызова синтаксиса LOAD DATA MySql в более NET-ориентированном виде. Класс требует, чтобы файл значений с разделителями-запятыми загружался и очень быстро.

Таким образом, ваша задача состояла бы в том, чтобы прочитать все ваши записи Sql Compact в datatable, а затем, используя streamwriter или специализированный CSV Writer, записывайте все в файл.

Тогда код для загрузки данных в таблицу MySql просто как этот

string connStr = "server=localhost;user=root;database=........"; 
using(MySqlConnection conn = new MySqlConnection(connStr)) 
{ 
    MySqlBulkLoader bl = new MySqlBulkLoader(conn); 
    bl.TableName = "yourdestinationtable"; 
    bl.FieldTerminator = "\t"; 
    bl.LineTerminator = "\n"; 
    bl.FileName = "path_to_your_comma_separated_value_file"; 
    try 
    { 
     conn.Open(); 
     int count = bl.Load(); 
    } 
} 
+0

У меня есть много дублирующихся значений, которые мне не нужно вставлять, есть ли проблема с использованием этого bulkLoader? – user1788654

+0

Вы можете вставить все свои данные в отдельную временную таблицу, а затем запустить хранимую процедуру, которая сверяет данные. Все это будет выполняться на сервере и, следовательно, не повлияет на время, необходимое для загрузки данных – Steve