我正在为Grepolis创建一个应用程序,这是一款在线战争游戏,您可以与数千名其他玩家一起玩游戏。我正在http://en12.grepolis.com/data/players.txt连接到一个文本文件并将其下载到WebClient.DownloadString中。然后我将其分解为“\ n”并将每个字符串拆分为“,”。每行包含玩家ID,名称,联盟_用户,积分,等级和城镇(玩家拥有的城镇数量)。最后一次计数超过60000。我在大约10分钟内将它们全部上传到本地数据库,现在对每一行进行更新,以便在此过程中删除0点上的所有玩家,并更新自上次更新以来已更改的任何人。问题是,即使只是更新到目前为止已经花了10多分钟。
有没有真正快速的方法来做我想做的事情?以下是我认为相关的所有代码:
文件:Global.asax.cs
protected void Application_Start(object sender, EventArgs e)
{
WebClient wc = new WebClient();
String str = wc.DownloadString("http://en12.grepolis.com/data/players.txt");
String[] players = str.Split('\n');
foreach (String player in players)
{
String[] playerInfo = player.Split(',');
ContentManager cm = new ContentManager();
int id = 0;
String name = "";
int alliance_id = 0;
int points = 0;
int rank = 0;
int towns = 0;
try
{
int.Parse(playerInfo[0]);
id = int.Parse(playerInfo[0]);
}
catch
{
}
try
{
name = playerInfo[1];
}
catch
{
}
try
{
int.Parse(playerInfo[2]);
alliance_id = int.Parse(playerInfo[2]);
}
catch
{
}
try
{
int.Parse(playerInfo[3]);
points = int.Parse(playerInfo[3]);
}
catch
{
}
try
{
int.Parse(playerInfo[4]);
rank = int.Parse(playerInfo[4]);
}
catch
{
}
try
{
int.Parse(playerInfo[5]);
towns = int.Parse(playerInfo[5]);
}
catch
{
}
if (points > 0 && towns > 0 && id > 0 && !name.Equals(""))
{
try
{
cm.UpdatePlayer(id, name, alliance_id, points, rank, towns);
}
catch
{
}
}
else
{
try
{
cm.DeletePlayer(id);
}
catch
{
}
}
}
}
文件:ContentManager.cs
public class ContentManager : IHttpModule
{
SqlDataSource conn = new SqlDataSource(WebConfigurationManager.ConnectionStrings["DevConn"].ConnectionString, "");
public void UpdatePlayer(int id, String name, int alliance_id, int points, int rank, int towns) {
conn.UpdateCommandType = SqlDataSourceCommandType.StoredProcedure;
conn.UpdateCommand = "UpdatePlayer";
conn.UpdateParameters.Clear();
conn.UpdateParameters.Add("id", id.ToString());
conn.UpdateParameters.Add("name", name);
conn.UpdateParameters.Add("alliance_id", alliance_id.ToString());
conn.UpdateParameters.Add("points", points.ToString());
conn.UpdateParameters.Add("rank", rank.ToString());
conn.UpdateParameters.Add("towns", towns.ToString());
conn.Update();
}
public void DeletePlayer(int id)
{
conn.DeleteCommandType = SqlDataSourceCommandType.StoredProcedure;
conn.DeleteCommand = "DeletePlayer";
conn.DeleteParameters.Clear();
conn.DeleteParameters.Add("id", id.ToString());
conn.Delete();
}
}
答案 0 :(得分:3)
您一次处理一个玩家,您需要进行批量上传。
您需要处理FOR循环中的所有用户,然后执行“批量插入”。
在我的工作中,我可以以我的HD可以读取的速度批量插入。
警告提示,批量插入会锁定表格,因此如果您计划在导入过程中使表格可读,则可能必须为批量插入设置批次。
例如:100k行,10k批次。 1)锁定表 2)开始导入直到10k行 3)解锁表 4)如果要提交更多行,请转到1
在第3步和第4步之间,会有一个中断,其他查询可能针对该表运行。
SQL和.NET管理几乎所有这些,我刚刚为你打破了逻辑。您需要做的就是阅读批量插入和批处理,一旦获得它就会很容易。
答案 1 :(得分:2)
每当我不得不这样做时,我已将数据输出到临时文本文件,然后使用Bulk Insert将数据转储到数据库中。