Ускорение запроса PostgreSQL, где данные находятся между двумя датами - PullRequest
6 голосов
/ 17 марта 2010

У меня есть большая таблица (> 50 м строк), в которой есть некоторые данные с идентификатором и отметкой времени:

id, timestamp, data1, ..., dataN

... с индексом из нескольких столбцов на (id, timestamp).

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

SELECT * FROM mytable WHERE id = x AND timestamp BETWEEN y AND z

В настоящее время это занимает более 2 минут на высокопроизводительном компьютере (2 x 3 ГГц двухъядерные Xeons с HT, 16 ГБ ОЗУ, 2 x 1 ТБ дисков в RAID 0), и я бы очень хотел ускорить его.

Я нашел этот совет , который рекомендует использовать пространственный индекс, но пример, который он дает, относится к IP-адресам. Тем не менее, увеличение скорости (с 436 до 3 с) впечатляет.

Как я могу использовать это с метками времени?

Ответы [ 3 ]

6 голосов
/ 17 марта 2010

Этот совет подходит только тогда, когда у вас есть два столбца A и B и используются такие запросы, как:

where 'a' between A and B

Это не так:

where A between 'a' and 'b'

Использование индекса на date(column) вместо column может немного ускорить его.

1 голос
/ 17 марта 2010

Не могли бы вы ОБЪЯСНИТЬ запрос для нас? Тогда мы знаем, как база данных выполняет ваш запрос. А как насчет конфигурации? Каковы настройки для shared_buffers и work_mem? А когда вы (или ваша система) последний вакуум и анализировали? И, наконец, какую ОС и pgSQL-версию вы используете?

Вы можете создавать замечательные индексы, но без надлежащих настроек база данных не сможет использовать их очень эффективно.

0 голосов
/ 17 марта 2010

Убедитесь, что индекс равен TableID + TableTimestamp, и вы выполняете запрос вроде:

SELECT
    ....
    FROM YourTable
    WHERE TableID=..YourID.. 
        AND TableTimestamp>=..startrange.. 
        AND TableTimestamp<=..endrange..

если вы примените функции к столбцу TableTimestamp таблицы в WHERE, вы не сможете полностью использовать индекс.

если вы уже все это делаете, значит, ваше оборудование может не справиться с этой задачей.

если вы используете версию 8.2 или новее, вам следует попробовать:

WHERE (TableID, TableTimestamp) >= (..YourID.., ..startrange.. ) 
    and (TableID, TableTimestamp) <= (..YourID.., ..endrange..)
...