Почему postgresql не начинает немедленно возвращать строки - PullRequest
6 голосов
/ 08 января 2010

Следующий запрос возвращает данные сразу:

SELECT time, value from data order by time limit 100;

Без предложения limit требуется много времени, чтобы сервер начал возвращать строки:

SELECT time, value from data order by time;

Я наблюдаю это как с помощью инструмента запросов (psql), так и при запросах с использованием API.

Вопросы / проблемы:

  • Объем работы, которую должен выполнить сервер перед началом возврата строк, должен быть одинаковым для обоих операторов выбора. Правильно?
  • Если так, то почему задержка в случае 2?
  • Есть ли какая-то фундаментальная проблема СУРБД, которую я не понимаю?
  • Есть ли способ заставить postgresql начать возвращать строки результатов клиенту без паузы, также для случая 2?
  • РЕДАКТИРОВАТЬ (см. Ниже) . Похоже, setFetchSize является ключом к решению этой проблемы. В моем случае я выполняю запрос из python, используя SQLAlchemy. Как я могу установить эту опцию для одного запроса (выполняется session.execute) ? Я использую драйвер psycopg2.

Столбец time является первичным ключом, кстати.

EDIT:

Я полагаю, что этот отрывок из документации драйвера JDBC описывает проблему и подсказки по ее решению (мне все еще нужна помощь - см. Последний пункт списка выше):

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

и

Переключение кода в режим курсора так же просто, как установка размера выборки в операторе соответствующего размера. Установка размера выборки обратно в 0 приведет к кэшированию всех строк (поведение по умолчанию).

// make sure autocommit is off
conn.setAutoCommit(false);
Statement st = conn.createStatement();

// Turn use of the cursor on.
st.setFetchSize(50);

Ответы [ 2 ]

4 голосов
/ 08 января 2010

Драйвер psycopg2 dbapi буферизирует весь результат запроса перед возвратом каких-либо строк. Вам нужно будет использовать серверный курсор, чтобы постепенно получать результаты. Для SQLAlchemy см. server_side_cursors в документах и, если вы используете ORM, метод Query.yield_per () .

SQLAlchemy в настоящее время не имеет возможности установить это значение для отдельного запроса, но есть заявка с патчем для реализации этого .

0 голосов
/ 08 января 2010

Теоретически, поскольку ваш ORDER BY по первичному ключу, сортировка результатов не обязательна, и БД действительно может сразу возвращать данные в ключевом порядке.

Я бы ожидал, что способная БД заметит это и оптимизирует его. Похоже, что PGSQL нет. * пожимает плечами *

Вы не заметите никакого влияния, если у вас есть LIMIT 100, потому что очень быстро вытащить эти 100 результатов из БД, и вы не заметите никакой задержки, если они сначала собраны и отсортированы перед отправкой вашему клиенту.

Я предлагаю попробовать отбросить ORDER BY. Скорее всего, ваши результаты в любом случае будут правильно упорядочены по времени (может даже существовать стандарт или спецификация, предписывающая это, учитывая ваш PK), и вы можете получить результаты быстрее.

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