C# Mysql Вставить много строк, проблема производительности - PullRequest
0 голосов
/ 10 апреля 2020

Интересно, как я могу выполнить массовую вставку вместо выполнения этого метода каждый раз?

Когда я пытаюсь вставить 1000 строк, становится медленнее:

queryText = "INSERT INTO `player_items` (`player_id`, `item_id`, `count`) VALUES (@player_id, @item_id, @count)";
for (int i = 0; i < player.invenotrySize; i++)
{
    Item item = player.inventory.GetItem[i];
    MySqlParameter[] parameters = {
         new MySqlParameter("player_id", 1),
         new MySqlParameter("item_id", item.data.id),
         new MySqlParameter("count", item.amount),
    };

    ExecuteNonQuery(queryText, parameters);
}
public int ExecuteNonQuery(string queryText, params MySqlParameter[] parameters)
{
    int affectedRows = 0;
    using (MySqlConnection mySqlConnection = CreateConnection())
    {
        using (MySqlCommand mySqlCommand = new MySqlCommand(queryText, mySqlConnection))
        {
            mySqlCommand.CommandType = CommandType.Text;
            mySqlCommand.Parameters.AddRange(parameters);
            affectedRows = mySqlCommand.ExecuteNonQuery();
        }
    }

    return affectedRows;
}

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

INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);

Но я понятия не имею, как я могу сделать метод, чтобы позаботиться об этой настройке

Ответы [ 2 ]

3 голосов
/ 10 апреля 2020

Вы открываете и закрываете свое соединение для каждой отдельной вставки.

using (MySqlConnection mySqlConnection = CreateConnection())

Это очень дорогая процедура, и, следовательно, не совсем подходит для работы с БД.

Вы следует открыть соединение только один раз, а затем закрыть его, когда закончите. В зависимости от того, что делает ваше приложение, это может происходить при запуске приложения (или до выполнения первого запроса к БД), а затем при закрытии приложения (или после того, как вы убедитесь, что запросов к БД больше не будет).

Тогда, в идеале, вам также следует повторно использовать экземпляр SqlCommand. Но вы должны убедиться, что вы очищаете свои параметры между ними. Итак, у вас есть что-то вроде этого

int affectedRows = 0;
using (MySqlConnection mySqlConnection = CreateConnection())
{
    string queryText = "INSERT INTO `player_items` (`player_id`, `item_id`, `count`) VALUES (@player_id, @item_id, @count)";
    using (MySqlCommand mySqlCommand = new MySqlCommand(queryText, mySqlConnection))
    {
        mySqlCommand.CommandType = CommandType.Text;
        for (int i = 0; i < player.invenotrySize; i++)
        {
            Item item = player.inventory.GetItem[i];
                MySqlParameter[] parameters = {
                    new MySqlParameter("player_id", 1),
                    new MySqlParameter("item_id", item.data.id),
                    new MySqlParameter("count", item.amount)};

                mySqlCommand.Parameters.Clear();
                mySqlCommand.Parameters.AddRange(parameters);
                affectedRows += mySqlCommand.ExecuteNonQuery();
        }
    }
}
1 голос
/ 10 апреля 2020

Это не совсем чисто с вашим "ExecuteNonQuery" (сделайте многострочное решение вставки или просто изолируйте / одиночный класс соединения, как решение выше, будет лучше), но вы можете построить весь запрос перед выполнением вместо get / add подключите, замените, запустите foreach player.

queryText = "INSERT INTO `player_items` (`player_id`, `item_id`, `count`) VALUES";
for (int i = 0; i < player.invenotrySize; i++)
{
    Item item = player.inventory.GetItem[i];
    MySqlParameter[] parameters = {
         new MySqlParameter("player_id_"+i, 1),
         new MySqlParameter("item_id_"+i, item.data.id),
         new MySqlParameter("count_"+i, item.amount),
    };
    queryText+= " (@player_id_"+i+", @item_id_"+i+", @count_"+i+"),";

}
//remove the last ,
queryText= queryText.Remove(queryText.Length - 1)+";";

ExecuteNonQuery(queryText, parameters);

Altnernate для пропуска параметров, если вы уверены в своих данных.

Item item = player.inventory.GetItem[i];
queryText+= " (1, "+item.data.id+", "+item.amount+"),";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...