【问题标题】:C# add thousands of rows from text file to database very quicklyC# 非常快速地将数千行从文本文件添加到数据库
【发布时间】:2011-06-27 18:09:04
【问题描述】:

我正在为 Grepolis 创建一个应用,这是一款在线战争游戏,您可以在其中与数以千计的其他玩家一起玩。我正在连接到http://en12.grepolis.com/data/players.txt 的文本文件并将其下载到WebClient.DownloadString。然后我将其拆分为“\n”并将每个字符串拆分为“,”。每行包含玩家 id、姓名、alliance_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();
    }
}

【问题讨论】:

    标签: c# sql-server sql-server-2008 web-applications webforms


    【解决方案1】:

    您一次处理一个播放器,您需要进行批量上传。

    您需要处理 FOR 循环中的所有用户,然后执行“批量插入”。

    在我的工作中,我可以以我的 HD 可以读取的速度批量插入。

    警告,大容量插入会锁定表,因此如果您打算在导入期间让表完全可读,则可能必须为大容量插入设置批处理。

    例如:100k 行,10k 批次。 1)锁表 2) 开始导入直到 10k 行 3) 解锁表 4) 如果要提交更多行,请转到 1

    在第 3 步和第 4 步之间,会有一个中断,其他查询可能会针对该表运行。

    SQL 和 .NET 几乎可以管理所有这些,我刚刚为您解释了逻辑。您需要做的就是阅读批量插入和批处理,一旦您获得它,这将看起来非常容易。

    【讨论】:

      【解决方案2】:

      过去每当我不得不这样做时,我都会将数据输出到一个临时文本文件,然后使用Bulk Insert 将数据转储到数据库中。

      【讨论】:

      • 谢谢。我正在尝试使用它,但我正在使用变量设置文件名(通过参数输入到更新过程中)。我正在使用 Server.MapPath("/App_Data/players.txt") 但它在“C:”上抛出错误。我认为这是导致问题的结肠。已尝试 URL 和 HTML 编码无济于事。有什么想法是什么原因造成的?
      • 路径是相对于SQL服务器的,所以只有在应用程序框和sql框共享同一个C盘时才有效。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-11
      • 2015-07-29
      • 1970-01-01
      • 1970-01-01
      • 2013-02-03
      • 2013-01-12
      • 1970-01-01
      相关资源
      最近更新 更多