Как улучшить скорость обновления SQLite - PullRequest
1 голос
/ 02 мая 2020

Я пишу несогласного бота, который обновляет баланс людей, и люди получают денежное вознаграждение за каждое отправляемое сообщение.

Я использую базу данных SQLite для этого. Я протестировал вставку большого количества записей в очередь, и в итоге потребовалось ~ 6,5 мс на каждый запрос на обновление, причем 5,5 мс было потрачено на сам запрос на обновление, а оставшиеся 1 мс использовались для проверки базы данных, если пользователь с запись существует и строит строки запроса.

Запросы обновления состоят из строк: (с верхней строкой, являющейся запросом)

  UPDATE exp12345678 SET exp = 68 , dummy = 159 WHERE userid = 54004700
  PreparedStatement pstmt = conn.prepareStatement(query);
   pstmt.executeUpdate();

И запрос вставки имеет строку ( с верхней строкой - sql String).

INSERT INTO exp12345678(userid, exp, dummy) VALUES(?,?,?)
PreparedStatement pstmt = conn.prepareStatement(sql);
                for (int i = 1; i <= args.length; i++) {
                    pstmt.setLong(i, mutationValues[i - 1]);
                }
                pstmt.executeUpdate();

Я попытался использовать систему очередей с несколькими потоками, разделяя пользователей между потоками на основе их использованного идентификатора (если я использую 2 потока, то я будет распространять запросы номеров идентификаторов пользователей в поток 1, в то время как запросы номеров идентификаторов пользователей будет четным в поток 2). Что не помогло решить проблему.

Я не уверен, как я мог бы go решить эту проблему. Я использую SQLite.

Дополнительные сведения: запросы выполняются по одному за раз, и это необходимо, потому что, если пользователь запрашивает какое-либо значение, ему необходимо знать, является ли его текущий баланс достаточным или нет.

Редактировать: я использую эти SQL вызовы для создания таблицы:

CREATE TABLE IF NOT EXISTS exp12345678 (
 id integer PRIMARY KEY,
 userid bigint,
 exp bigint,
 dummy bigint
);

И это для получения значений от пользователя (для создания запроса на обновление).

SELECT * FROM exp12345678 WHERE userid = 10437023

Теперь все, что я делаю, это пытаюсь добавить мутацию к существующему пользователю. Нет ли более быстрого способа сделать это?

Ответы [ 2 ]

1 голос
/ 03 мая 2020

Я не совсем соблюдаю ваши ограничения в отношении необходимости делать одну запись за раз, поэтому это может быть бесполезно, но выполнение одного обновления за один раз имеет тенденцию быть медленным. Пакетные вставки JDB C могут оказывать драматическое c влияние на время, необходимое для выполнения нескольких запросов. Ниже приведен пример этого на основе вашего кода.

try (PreparedStatement pstmt = conn.prepareStatement(sql)) {

        int rowCount = 0;
        for (long mutationValue : mutationValues) {
            pstmt.setLong(i, mutationValue);
            pstmt.addBatch();
            rowCount++;
            if (rowCount % BATCH_SIZE == 0) { // You may have to do some experimentation to find a good value.
                pstmt.executeBatch();
            }
        }
        if (rowCount % BATCH_SIZE != 0) {
            pstmt.executeBatch();
        }
    }
0 голосов
/ 02 мая 2020

Вы проверяете, существует ли пользователь (SELECT), а затем вставляете (INSERT) или обновляете его (UPDATE).

Банки SELECT и UPDATE очень выигрыш от индекса:

create index ix1 on exp12345678 (userid);

Измерьте время снова после создания индекса.

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