【发布时间】:2013-08-02 02:31:45
【问题描述】:
我必须在 MySql 表中插入 90Mb 的数据,并且我正在使用 INSERT IGNORE 命令来避免重复键的异常。性能是每秒 8 条记录,但似乎很慢。我可以快点吗?
附言因为我从 sql 紧凑型数据库中读取数据,所以我正在为每条记录插入记录
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();
}
}
【问题讨论】:
-
一种方法是在你的循环中构建一个字符串构建器并在外部进行插入......这将减少每条记录访问数据库的热量
-
@Sam 你的意思是每次插入一组记录?
-
可能你的代码可能被 otpmized 了很多,但没有看到它.....
-
是的,它可以节省您每次点击 db 并进行批量插入
-
进一步说明@Sam 的观点,我经常这样做。可能最简单的方法是敲一个类来做插入。实例化该类的一个实例。对于每条记录,您将行传递给对象,它决定是否有足够的行来添加。如果不是,它将该行添加到等待行的存储中,如果有足够的行,它会立即对所有这些行执行 INSERT IGNORE,然后清除等待行的存储。处理完所有行后,您将销毁对象,并在类的 destruct 方法中进行最终插入。
标签: c# mysql sql-server-ce