Следующий запрос возвращает данные сразу же:
SELECT time, value from data order by time limit 100;
Без предельного пункта требуется много времени, прежде чем сервер начинает возвращать строки:
SELECT time, value from data order by time;
Я наблюдаю это оба при помощи инструментального средства формирования запросов (psql
) и при запросах использования API.
Вопросы/проблемы:
setFetchSize
ключ к решению этого. В моем случае я выполняю запрос из Python, с помощью SQLAlchemy. Как я могу установить ту опцию для единого запроса (выполняемый session.execute
)? Я использую psycopg2 драйвер.Столбец time
первичный ключ, BTW.
Править:
Я полагаю, что эта выборка из документации драйвера 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);
Драйвер psycopg2 dbapi буферизирует весь результат запроса, прежде чем возвращать какие-то строки. Для инкрементального получения результатов необходимо использовать курсор на стороне сервера. Для SQLAlchemy смотрите курсоры_side_cursors сервера в документации и если вы используете ORM, то метод Query.yield_per().
SQLAlchemy в настоящее время не имеет возможности установить это на один запрос, но есть билет с патчем для реализации этого.
Теоретически, поскольку ваше ЗАКАЗАНИЕ БД осуществляется по первичному ключу, то не должно быть необходимости в каких-то результатах, и БД действительно может сразу же возвращать данные в ключевом порядке.
Я бы ожидал, что способная БД заметит это и оптимизирует для этого. Похоже, что PGSQL - нет. * пожимание плечами *
Вы не заметите никакого эффекта, если у вас LIMIT 100, потому что очень быстро вытащить эти 100 результатов из БД, и вы не заметите никакой задержки, если они сначала будут собраны и отсортированы перед отправкой вашему клиенту.
Я предлагаю попробовать сбросить ЗАКАЗЧИК ПО ЗАКАЗЧИКУ. Скорее всего, ваши результаты в любом случае будут правильно заказаны ко времени (может быть даже стандарт или спецификация, которая предписывает это, учитывая вашу PK), и вы можете получить свои результаты быстрее.
.