C# MYSQL中在表之间移动数据的最佳方法
我有一个关于性能的问题。这是我的设想 我有一个MYSQL数据库和一个应用程序,它可以根据查询的条件将记录从一个表移动到另一个表。这样做的方式是:C# MYSQL中在表之间移动数据的最佳方法,c#,mysql,C#,Mysql,我有一个关于性能的问题。这是我的设想 我有一个MYSQL数据库和一个应用程序,它可以根据查询的条件将记录从一个表移动到另一个表。这样做的方式是: foreach(object obj in list) { string id = obj.ToString().Split(',')[0].Trim(); string query = " insert into old_records select * from testes where id='" +
foreach(object obj in list)
{
string id = obj.ToString().Split(',')[0].Trim();
string query = " insert into old_records select * from testes where id='" +
id + "';" + " delete from testes where id='" + id +"'";
DB _db = new DB();
_db.DBConnect(query);
这是我连接数据库的方式:
DataTable _dt = new DataTable();
MySqlConnection _conn = new MySqlConnection(connectionString);
MySqlCommand _cmd = new MySqlCommand
{
Connection = _conn,
CommandText = query
};
MySqlDataAdapter _da = new MySqlDataAdapter(_cmd);
MySqlCommandBuilder _cb = new MySqlCommandBuilder(_da);
_dt.Clear();
try
{
_conn.Open();
_cmd.ExecuteNonQuery();
_da.Fill(_dt);
}
catch (MySqlException ex)
{
Console.WriteLine(ex.Message);
}
finally
{
if (_conn != null) _conn.Close();
}
return _dt;
所以我的问题是,表中有4000行,将所有记录从一个表移动到另一个表需要很多时间,特别是通过网络。有没有办法让这更快
我已经做了一些阅读,有几个选项可以处理来自DB的数据,比如数据适配器、读取器、集合和表。在这种情况下,哪一个更快?我应该使用另一种方法吗?我可能错了,但为了加快速度,您没有什么办法。毕竟,您希望获取整个表数据并将其信息插入到另一个表中。如果您的桌子不小,这个过程将需要一些时间。但是,您可以尝试使用下面的代码。它应该做到这一点,并节省一些时间
INSERT INTO TABLE2 (FIELDNAME_IN_TABLE2, FIELDNAME2_IN_TABLE2)
SELECT FIELDNAME_IN_TABLE1, FIELDNAME2_IN_TABLE1
FROM TABLE1
我看到的两件事是,首先,每次插入都要打开和关闭连接,这通常是最昂贵的操作,所以您不想这样做。您还可以尝试对它们进行批处理,而不是立即进行。当你这样做时,你必须小心,因为事情可能在大更新的中间中断,所以你想在事务中做事情。在不太了解您的数据结构的情况下,我对您的方法进行了重构,一次进行100次批处理。首先创建一个名为moveitems的小助手方法,它接受一个连接和一个id列表。不要在这里尝试捕捉,稍后你会看到原因 注意:此方法不使用参数,我强烈建议您将其更改为使用参数
private static void MoveItems(MySqlConnection conn, List<string> moveList)
{
string query = string.Format("insert into old_records select * from testes where id IN({0});" + " delete from testes where id IN({0})", string.Join(",", moveList.ToArray()));
var cmd = new MySqlCommand
{
Connection = conn,
CommandText = query
};
cmd.ExecuteNonQuery();
}
private static void MoveItems(MySqlConnection conn,List moveList)
{
string query=string.Format(“插入到旧的_记录中,从({0})中id所在的测试中选择*;”+“从({0})中id所在的测试中删除)”,string.Join(“,”,moveList.ToArray());
var cmd=新的MySqlCommand
{
连接=连接,
CommandText=查询
};
cmd.ExecuteNonQuery();
}
接下来,您将更改main方法以打开数据库连接一次,然后每次调用这个方法100个id。此方法将有一个try-catch,因此,如果对MoveItems的调用引发异常,则将在此主方法中捕获该异常
// the using statement will call your dispose method
using (var conn = new MySqlConnection(connectionString))
{
// open the connection and start the transaction
conn.Open();
var transaction = conn.BeginTransaction();
// createa list to temporarily store the ids
List<string> moves = new List<string>();
try
{
// clean the list, do the trim and get everything that's not null or empty
var cleanList = list.Select(obj => obj.ToString().Split(',')[0].Trim()).Where(s => !string.IsNullOrEmpty(s));
// loop over the clean list
foreach (string id in cleanList)
{
// add the id to the move list
moves.Add("'" + id + "'");
// batch 100 at a time
if (moves.Count % 100 == 0)
{
// when I reach 100 execute them and clear the list out
MoveItems(conn, moves);
moves.Clear();
}
}
// The list count might not be n (mod 100) therefore see if there's anything left
if (moves.Count > 0)
{
MoveItems(conn, moves);
moves.Clear();
}
// wohoo! commit the transaction
transaction.Commit();
}
catch (MySqlException ex)
{
// oops! something happened roll back everything
transaction.Rollback();
Console.WriteLine(ex.Message);
}
finally
{
conn.Close();
}
}
//using语句将调用您的dispose方法
使用(var conn=new MySqlConnection(connectionString))
{
//打开连接并启动事务
conn.Open();
var事务=conn.BeginTransaction();
//创建一个列表以临时存储ID
列表移动=新列表();
尝试
{
//清理列表,进行修剪,得到所有不为null或空的内容
var cleanList=list.Select(obj=>obj.ToString().Split(',)[0].Trim()).Where(s=>!string.IsNullOrEmpty(s));
//循环浏览干净的列表
foreach(cleanList中的字符串id)
{
//将id添加到移动列表中
移动。添加(“”+id+“”);
//一次100批
如果(moves.Count%100==0)
{
//当我达到100时,执行它们并清除列表
移动项目(连接、移动);
移动。清除();
}
}
//列表计数可能不是n(mod 100),因此请查看是否还有剩余内容
如果(moves.Count>0)
{
移动项目(连接、移动);
移动。清除();
}
//哇!提交事务
Commit();
}
捕获(MySqlException-ex)
{
//哎呀!发生了什么事把所有的东西都滚回去
transaction.Rollback();
控制台写入线(例如消息);
}
最后
{
康涅狄格州关闭();
}
}
你可能得用那100个数字。我记得当我经常使用MySQL时,我看到了执行IN和给它一个Or语句列表(Id='ID1'或Id='ID2'…)之间的一些性能差异。但是执行40条语句或80条语句肯定会有更好的性能,打开数据库连接一次而不是4000次也会有更好的性能。这会改变吗?通过移动、insert to new和delete OF old?它应该将数据从一个表移动到另一个表,但是它不会删除任何记录。您的第一点是正确的,但您的代码只有在数据库位于同一服务器上时才起作用。如果是通过网络连接的,您需要链接服务器。@gunr217我已经在网络上运行了。。每个记录大约需要2秒钟:(想象一下4000!@TommyNaidich,但是当它被复制到第二个记录时,我还需要从第一个记录中删除它……我需要移动而不是复制。