MySQL медленные вставки - PullRequest
0 голосов
/ 06 апреля 2020

У меня есть сервер баз данных MySql 8, работающий локально на приличном игровом ноутбуке. Когда я пытаюсь вставить количество записей (500 КБ), хранящихся в структуре в памяти в Java, с помощью следующего кода, это очень медленно, мы говорим, может быть, самое большее 1000 записей в минуту.

Я действительно не знаю, где искать отладочную информацию или какие показатели я должен предоставить здесь, чтобы помочь ответить на этот пост, поэтому, если у вас есть какие-либо рекомендации или дополнительная информация, которую я могу предоставить, пожалуйста, дайте мне знать.

Я временно работал над этим, сохраняя данные в базе данных H2 в памяти, но на самом деле я хотел бы сохранить их и запросить их на досуге, используя MySql workbench.

        PreparedStatement ps = conn.prepareStatement(insertSQL);


        ArrayList<String> stocks = new ArrayList<String>();
        for (Spread spread : spreads) {


            ps.setInt(1, spread.buyFeedId);
            ps.setInt(2, spread.sellFeedId);
            ps.setString(3, spread.stock);
            ps.setString(4, spread.buyExchange);
            ps.setString(5, spread.sellExchange);
            ps.setTimestamp(6, new Timestamp(spread.spreadDateTime.toInstant().toEpochMilli())); 
            ps.setDouble(7, spread.buyPrice);
            ps.setDouble(8, spread.sellPrice);
            ps.setDouble(9, spread.diff);
            ps.setInt(10, spread.askSize);
            ps.setInt(11, spread.bidSize);

            ps.execute();

Ответы [ 3 ]

1 голос
/ 06 апреля 2020

В PHP у нас есть библиотека PDO, позволяющая фактически объединять вставки в одну транзакцию, используя:

$sql = 'my sql statement';
$Conn = DAO::getConnection();
$stmt = $Conn->prepare($sql);
$Conn->beginTransaction();
foreach($data as $row)
{
    // now loop through each inner array to match bound values
    foreach($row as $column => $value)
    {
        $stmt->bindValue(':' . $column, $value, PDOUtils::getPDOParam($value));
    }                
    $stmt->execute();
}
$Conn->commit(); 

В вашем случае с 1000+ вставками потребуется только одна транзакция. Я не java, но наверняка есть эквивалент.

0 голосов
/ 06 апреля 2020

Пакетная вставка строк. То есть, построить один INSERT для каждых 100-1000 строк. Это будет работать примерно в 10 раз быстрее. Использование «транзакции» - это менее эффективный способ пакетирования.

Вот одно из обсуждений Java + Пакет: https://www.viralpatel.net/batch-insert-in-java-jdbc/

Поиск других возможных ответов на этом сайте:

site:stackoverflow.com  java  MySQL  batch  INSERT

Другое ускорение должно измениться на

innodb_flush_log_at_trx_commit = 2

Это соотношение скорости и надежности - в пользу скорости.

0 голосов
/ 06 апреля 2020

Если у вас под рукой есть все записи по 500 Кб, и если вы просто хотите вставить, не вставляйте операцию построчно, а используйте функциональность BCP (программа массового копирования).

Прочтите о mysqlimport или LOAD Команды IN FILE и попробуйте реализовать.

...