2016-06-11 4 views
1

Рассмотрим чтение через все ряды большой таблицы с MySQL Connector/C++:Обработка большого количества строк фрагментированное/небуферизован

std::unique_ptr<sql::ResultSet> res(
       stmt->executeQuery("SELECT a, b FROM table")); 
while (res->next()) { 
    handle(res->getUInt64(1), res->getDouble(2)); 
} 

Из documentation: MySQL Connector

это письмо,/C++ возвращает результаты буферизации для объектов Statement. Буферизованные результирующие наборы кэшируются на клиенте. Драйвер всегда будет получать все данные независимо от того, насколько велик результат. комплект есть. Ожидается, что будущие версии соединителя возвратят буферизованные и небуферизованные результаты для объектов Statement.

Это соответствует моему наблюдению. На меньших таблицах (~ 1e8 строк) это занимает 3 минуты до первого handle, остальное завершается через 7 секунд. Для больших таблиц (~ 1e10 строк) он просто продолжает накапливать больше памяти, пока не закончится память.

Как можно обрабатывать такие запросы без исчерпания памяти при разумной эффективности с сжатым кодом?

Должен сказать, что мне трудно поверить, что не должно быть прозрачного решения. Кажется, такая очевидная оптимизация делает потоковое воспроизведение результата в слое MySQL.

Примечание: handle находится в библиотеке, намного быстрее, чем сервер MySQL может предоставлять данные. Он должен обрабатывать строки в естественном порядке, поэтому он не может быть распараллелен.

+0

Это похоже на выполнимость сейчас. См. «TYPE_FORWARD_ONLY» здесь: https://dev.mysql.com/doc/relnotes/connector-cpp/en/news-1-0-5.html – logidelic

+0

Возможный дубликат [Mysql Connector C++ Unbuffered ResultSet C++] (https: //stackoverflow.com/questions/42097354/mysql-connector-c-unbuffered-resultset-c) – logidelic

+0

Печально, что в документации не упоминаются характеристики производительности/памяти 'TYPE_FORWARD_ONLY'. Я немного неохотно закрываюсь как дубликат, потому что другой вопрос менее конкретный. Также по-прежнему нет ответа относительно потокового потокового решения. – Zulan

ответ

0

Одним из способов сделать это, а не точно прозрачно, было бы выполнение chunking на клиенте, поэтому получение подсчета общих строк и использование ключевого слова LIMIT в запросе в сочетании с циклом для запуска нескольких запросов для который имеет приемлемое использование памяти. Вы должны быть уверены, что содержимое таблицы не менялось тем временем, чтобы иметь возможность сделать это.

Смежные вопросы