C # очень быстро добавляет тысячи строк из текстового файла в базу данных - PullRequest
1 голос
/ 15 февраля 2011

Я создаю приложение для Grepolis, онлайновой военной игры, в которой вы играете вместе с тысячами других игроков.Я подключаюсь к текстовому файлу на http://en12.grepolis.com/data/players.txt и загружаю его в WebClient.DownloadString.Затем я делю это на "\ n" и разделяю каждую из этих строк на ",".Каждая строка содержит идентификатор игрока, имя, 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();
    }
}

Ответы [ 2 ]

3 голосов
/ 15 февраля 2011

Вы обрабатываете по одному игроку за раз, вам нужно выполнить пакетную загрузку.

Вам необходимо обработать всех пользователей в цикле FOR, а затем выполнить «массовую вставку».

На моей работе я могу выполнять массовую вставку со скоростью, с которой мой HD может читать.

Предупреждение: массовая вставка блокирует таблицу, поэтому вам может потребоваться установить пакеты для массовой вставки, если вы планируете, чтобы таблица вообще читалась во время импорта.

Например: 100 тыс. Строк с партиями по 10 тыс. 1) замок стол 2) начать импорт до 10k строк 3) разблокировать стол 4) если больше строк для фиксации, переходите к 1

Между шагами 3 и 4 произойдет перерыв, когда к таблице могут выполняться другие запросы.

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

2 голосов
/ 15 февраля 2011

Всякий раз, когда мне приходилось делать это в прошлом, я выводил данные во временный текстовый файл, а затем использовал Массовая вставка для выгрузки данных в базу данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...