База данных - это около 1 миллиарда строк, работающих на Core2Quad с 8 ГБ ОЗУ на Ubuntu 64bit. Конечно, этот запрос не должен занимать полчаса
Это занимает полчаса из-за того, как вы настраиваете свои индексы.
Ваш запрос не имеет многостолбцовых индексов, которые он может использовать для перехода прямо к нужным строкам. Это делает следующее лучшее: сканирование растровых индексов по едва отобранным индексам и сортировка топ-3 результирующего набора.
Два рассматриваемых индекса, по ценным бумагам и на дату, дают 1,3 млн и 2,3 млн строк соответственно. Их объединение будет мучительно медленным, потому что вы случайно просматриваете более миллиона строк и фильтруете каждую из них.
Добавляя оскорбление, ваша структура данных такова, что два сильно коррелированных поля (дата и время) хранятся и обрабатываются отдельно. Это сбивает с толку планировщика запросов, поскольку Postgres не собирает данные корреляции. Таким образом, ваши запросы почти всегда прибегают к фильтрации огромных наборов данных и упорядочению отфильтрованного набора по отдельным критериям.
Я бы предложил следующие изменения:
Измените таблицу и добавьте столбец datetime типа timestamp with time zone
. Объедините в нем свои столбцы даты и времени.
Удалите соответственно поля даты и времени, а также индексы на них. Также сбросьте индекс безопасности.
Создать индекс (безопасность, дата и время). (И не возитесь с нулями в первую очередь / нулями в последнюю очередь, если ваши критерии заказа не содержат эти пункты тоже.)
По вашему усмотрению добавьте отдельный индекс on (datetime) или on (datetime, security), если вам когда-либо понадобится выполнить запросы, которые выполняют статистику по всем сделкам за день или диапазон дат.
проанализируйте весь беспорядок, как только вы закончите с вышеописанным.
После этого вы сможете переписать ваш запрос следующим образом:
SELECT "TIME", "TRADEPRICE"
FROM "YEAR"
WHERE '2010-03-01 00:00:00' <= "DATETIME" AND "DATETIME" < '2010-03-01 10:16:00'
AND "SECURITY"='STW.AX'
AND "TYPE" = 'TRADE'
ORDER BY "DATETIME" ASC LIMIT 3
Это даст наиболее оптимальный план: получение трех верхних строк из отфильтрованного сканирования индекса (безопасность, дата и время), которое, как я ожидаю (поскольку у вас миллиард строк), займет максимум 25 мс.