Форум программистов, компьютерный форум, киберфорум
Java: Базы данных
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.88/25: Рейтинг темы: голосов - 25, средняя оценка - 4.88
0 / 0 / 0
Регистрация: 15.03.2016
Сообщений: 135

Получение и обработка данных из большой таблицы (200 млн строк)

09.07.2018, 14:12. Показов 5491. Ответов 7
Метки c, jd, jdbc, mysql (Все метки)

Студворк — интернет-сервис помощи студентам
У меня есть большая таблица MySQL с порядка 200 млн записей.

Я делаю такой запрос, используя JDBC:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public List<Pair<Long, String>> getUsersAll() throws SQLException {
        Connection cnn = null;
        CallableStatement cs = null;
        ResultSet rs = null;
        final List<Pair<Long, String>> res = new ArrayList<>();
        try {
            cnn = dataSource.getConnection();
            cs = cnn.prepareCall("select UserPropertyKindId, login from TEST.users;");
            rs = cs.executeQuery();
            while (rs.next()) {
                res.add(new ImmutablePair<>(rs.getLong(1), rs.getString(2)));
            }
            return res;
        } catch (SQLException ex) {
            throw ex;
        } finally {
            DbUtils.closeQuietly(cnn, cs, rs);
        }
    }

Дальше я должен обработать результат:

Java
1
2
3
4
5
6
7
List<Pair<Long, String>> users= dao.getUsersAll();
            if (CollectionUtils.isNotEmpty(users)) {
                for (List<Pair<Long, String>> partition : Lists.partition(users, 2000)) {
                    InconsistsUsers.InconsistsUsersCallable callable = new InconsistsUsers.InconsistsUsersCallable (new ArrayList<>(partition));
                    processExecutor.submit(callable);
                }
            }
Так как таблица очень большая и все данные выгружаются в память, падает с ошибкой:

Java
1
2
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 105,619 milliseconds ago.
Как я могу получать данные частями, что не выгружать сразу все в память. Может быть использовать курсор и складывать данные в какую-нибудь неблокирующую очередь и по мере прихода в нее данных их разгребать? Как это лучше сделать?

Структуру базы я менять не могу, все манипуляции нужно сделать из Java кода.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
09.07.2018, 14:12
Ответы с готовыми решениями:

Получение данных из textBox с свойством multiline с разных строк в разные поля таблицы
Никак не пойму как сделать что бы в бд добавлялись данные с каждой строки textbox с multiline в разные поля таблицы.Пишу на на C#.

Работа с большой базой (>1 млн записей)
Товарищи, помогите! Я недавно перешел на C# 2005, меня особенно интересует вопрос работы с большими базами (более 1 млн. записей) В...

Редактирование таблицы: разрешено редактировать только 200 строк
Извините за беспокойство. Прошу помощи.С Microsoft SQL Server 2008 никогда не работал. Знал бы как не спрашивал. Дело в чём есть БД...

7
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4576 / 2775 / 491
Регистрация: 28.04.2012
Сообщений: 8,780
09.07.2018, 14:25
Цитата Сообщение от Neo-X2006 Посмотреть сообщение
Как я могу получать данные частями, что не выгружать сразу все в память.
Очевидно делать partition не в коде по коллекции, а в БД при запросе на получение данных.
0
0 / 0 / 0
Регистрация: 15.03.2016
Сообщений: 135
09.07.2018, 14:35  [ТС]
Цитата Сообщение от korvin_ Посмотреть сообщение
Очевидно делать partition не в коде по коллекции, а в БД при запросе на получение данных.
Тогда возникнет другая проблема с производительностью, тк на больших лимитах и оффсетах запрос будет выполнятся очень долго.
0
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4576 / 2775 / 491
Регистрация: 28.04.2012
Сообщений: 8,780
09.07.2018, 16:53
Цитата Сообщение от Neo-X2006 Посмотреть сообщение
Тогда возникнет другая проблема с производительностью, тк на больших лимитах и оффсетах запрос будет выполнятся очень долго.
Тогда производи манипуляции по мере чтения ResultSet'а, например

Java
1
2
3
4
5
@FunctionalInterface
public interface UserConsumer {
 
    void accept(long userPropertyKindId, String login) throws SQLException;
}
Java
1
2
3
4
5
6
7
8
public void getUsersAll(UserConsumer consumer) throws SQLException {
 
    ...
        while (rs.next()) {
            consumer.accept(rs.getLong(1), rs.getString(2));
        }
    ...
}
Или делай Stream поверх ResultSet'а (возможно, существуют готовые реализации), только закрывать connection, statement и rs нужно будет в методе close стрима.
0
0 / 0 / 0
Регистрация: 15.03.2016
Сообщений: 135
09.07.2018, 17:30  [ТС]
Цитата Сообщение от korvin_ Посмотреть сообщение
Тогда производи манипуляции по мере чтения ResultSet'а, например
А разве в данном случае, он вычитает не все сразу данные?

Java
1
2
3
while (rs.next()) {
            consumer.accept(rs.getLong(1), rs.getString(2));
        }
Насколько правильно сделать так:

Java
1
2
stmt = con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);
Добавлено через 20 минут
Как вообще на стороне JDBC драйвера указать "Забирай данные пачками, по n элементов, а не грузи все сразу в паямять"?
0
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4576 / 2775 / 491
Регистрация: 28.04.2012
Сообщений: 8,780
09.07.2018, 20:31
Цитата Сообщение от Neo-X2006 Посмотреть сообщение
А разве в данном случае, он вычитает не все сразу данные?
Не обязательно, это зависит от драйвера и параметров Statement'а/ResultSet'а.

https://docs.oracle.com/javase... hSize-int-
https://docs.oracle.com/javase... hSize-int-

Цитата Сообщение от Neo-X2006 Посмотреть сообщение
Насколько правильно сделать так:

Java
1
stmt.setFetchSize(Integer.MIN_VALUE);
Вот так ни на сколько не правильно.

Цитата Сообщение от Neo-X2006 Посмотреть сообщение
"Забирай данные пачками, по n элементов, а не грузи все сразу в паямять"?
setFetchSize(n);

он и не грузит всё в память, он по-умолчанию работает с курсором. В зависимости от БД и драйвера, конечно.
Ты сам всё загружаешь сразу в память, в ArrayList.

Но вообще, с чего ты взял, что проблема в памяти?
com.mysql.jdbc.exceptions.jdbc4.Communic ationsException: Communications link failure
не выглядит как проблема с памятью.
0
0 / 0 / 0
Регистрация: 15.03.2016
Сообщений: 135
10.07.2018, 09:29  [ТС]
Цитата Сообщение от korvin_ Посмотреть сообщение
setFetchSize(n);
Насколько удалось понять отсюда https://dev.mysql.com/doc/conn... notes.html, из коробки в MySQL это не работает.

Цитата Сообщение от korvin_ Посмотреть сообщение
Но вообще, с чего ты взял, что проблема в памяти?
Мониторинг показал, что после запуска данной выгрузки, выжралась вся память на сервере.
0
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4576 / 2775 / 491
Регистрация: 28.04.2012
Сообщений: 8,780
10.07.2018, 10:58
Цитата Сообщение от Neo-X2006 Посмотреть сообщение
из коробки в MySQL это не работает.
Работает, только настроить надо, там же написано:

Another alternative is to use cursor-based streaming to retrieve a set number of rows each time. This can be done by setting the connection property useCursorFetch to true, and then calling setFetchSize(int) with int being the desired number of rows to be fetched each time:

Java
1
2
3
4
conn = DriverManager.getConnection("jdbc:mysql://localhost/?useCursorFetch=true", "user", "s3cr3t");
stmt = conn.createStatement();
stmt.setFetchSize(100);
rs = stmt.executeQuery("SELECT * FROM your_table_here");
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
10.07.2018, 10:58
Помогаю со студенческими работами здесь

Получение данных из текстового файла, чей вес от 200 Мб и больше
Здравствуйте, форумчане! Подскажите пожалуйста правильный метод получения текстовых данных в виде таблицы из текстового файла, где...

Создание большой таблицы из данных двух столбцов
Добрый день! Есть две достаточно большие колонки данных: примерно в 100 и в 1000 значений сответственно. Для загрузки в CRM нужно создать...

Обработка строк по условию, получение подстрок из строки! Консультация
Всем доброго времечка! Только начал изучать C#, так что сильно не пинать. Поставил себе для решения задачку: Имеем текстовый файл...

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

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20% kYBz3eJf3jQ
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
Использование значений реквизитов справочника в документе, с определенными условиями и правами
Maks 07.04.2026
1. Контроль срока действия договора Алгоритм из решения ниже реализован на примере нетипового документа "ЗаявкаНаРаботу", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если. . .
Доступность команды формы по условию
Maks 07.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: сделать доступной кнопку (команда формы "ЗавершитьСписание") при. . .
Уведомление о неверно выбранном значении справочника
Maks 06.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "НарядПутевка", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если в документе выбран неверный склад. . .
Установка Qt Creator для C и C++: ставим среду, CMake и MinGW без фреймворка Qt
8Observer8 05.04.2026
Среду разработки Qt Creator можно установить без фреймворка Qt. Есть отдельный репозиторий для этой среды: https:/ / github. com/ qt-creator/ qt-creator, где можно скачать установщик, на вкладке Releases:. . .
AkelPad-скрипты, структуры, и немного лирики..
testuser2 05.04.2026
Такая программа, как AkelPad существует уже давно, и также давно существуют скрипты под нее. Тем не менее, прога живет, периодически что-то не спеша дополняется, улучшается. Что меня в первую очередь. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru