Оптимизация вставок в базу данных SQLite с помощью JDBC - PullRequest
0 голосов
/ 27 марта 2020

Я пишу бэкэнд для java http-сервера для проекта класса, и мне нужно вставить несколько записей в базу данных, используя jdb c. Максимальное количество вставок, которые у меня есть за один раз, в настоящее время составляет 122, что требует колоссальных 18,7 для выполнения, около 6,5 вставок в секунду. Это невероятно медленно, так как сервер должен быть в состоянии ответить на запрос, который вставляет записи менее чем за 5 секунд, и реальный сервер должен быть во много раз быстрее. Я почти уверен, что это как-то связано с кодом или моим объявлением схемы таблицы, но я не могу найти узкое место нигде. Схема таблицы выглядит следующим образом:

CREATE TABLE Events (
    ID varchar(38) primary key,
    ownerName varchar(32) not null,
    personID varchar(38) not null,
    latitude float not null,
    longitude float not null,
    country varchar(64) not null,
    city varchar(128) not null,
    eventType varchar(8) not null,
    year int not null,
    foreign key (ownerName)
        references Users (userName)
            on delete cascade
            on update cascade,
    foreign key (ID)
        references People (ID)
            on delete cascade
            on update cascade
);

, а код для выполнения вставок представляет собой следующую функцию

public class EventAccessor {
    private Connection handle;
    ...

    public void insert(Event event) throws DataInsertException {
        String query = "insert into Events(ID,ownerName,personID,latitude,longitude,country,"
                 + "city,eventType,year)\nvalues(?,?,?,?,?,?,?,?,?)";

        try (PreparedStatement stmt = handle.prepareStatement(query)) {
            stmt.setString(1, event.getID());
            stmt.setString(2, event.getUsername());
            stmt.setString(3, event.getPersonID());
            stmt.setDouble(4, event.getLatitude());
            stmt.setDouble(5, event.getLongitude());
            stmt.setString(6, event.getCountry());
            stmt.setString(7, event.getCity());
            stmt.setString(8, event.getType());
            stmt.setInt(9, event.getYear());

            stmt.executeUpdate();
        } catch (SQLException e) {
            throw new DataInsertException(e.getMessage(), e);
        }
    }
}

Где Event - это класс, содержащий запись для схемы и DataInsertionException - это простое исключение, определенное в другом месте в API. Мне дали указание использовать PreparedStatement, потому что это, очевидно, "более безопасно", чем использование Statement, но у меня есть выбор, чтобы переключиться, поэтому, если это будет быстрее, я с радостью изменю код. Функция, которую я использую для вставки 122 записей, на самом деле является оберткой для массива Event объектов, которые выглядят так:

void insertEvents(Event[] events) throws DataInsertException {
    for (Event e : events) {
        insert(e);
    }
}

Я готов попробовать что угодно для повышения производительности на этом этапе.

1 Ответ

0 голосов
/ 27 марта 2020

Я отключил автоматическую фиксацию на соединении JDB C с connection.setAutoCommit(false), и производительность увеличилась более чем в 1000 раз. Новые тесты показывают, что вставка 122 записей была завершена всего за 0,008265739, со скоростью около 14 000 вставок в секунду, что ближе к тому, что я ожидал.

...