2015-06-30 4 views
1
  • Моя Postgres версия: "PostgreSQL 9.4.1, составленный Visual C++ построить 1800, 32-бит"
  • стол, который я буду иметь дело с; содержит столбцы
    1. eventtime - метки времени без часового пояса
    2. SerialNumber - символ различного (32)
    3. SourceId - целого

и 4 других столбцыPostgreSQL - Как уменьшить время выберите оператор excution

вот мой выбор заявление

SELECT eventtime, serialnumber 
    FROM t_el_eventlog 
    WHERE 
    eventtime at time zone 'CET' > CURRENT_DATE and 
    sourceid = '14'; 

время excution для приведенного выше запроса 59647ms

И в моем сценарии я г у 5 такого рода запросов (время excution = 59647ms * 5). Без использования часового пояса «CET» время выхода очень мало, но в моем случае я должен использовать часовой пояс «CET», и если я прав, то время высокого извлечения будет причиной этого часового пояса.

мой план запроса

enter image description here

текст запроса enter image description here

объяснить анализ запроса (без часового пояса) enter image description here

Есть в любом случае, что я могу уменьшить время excution запроса на мой выберите извещение

+0

Просьба отобразить план (ы) запроса. –

+0

@CraigRinger: я добавил план запроса в указанном выше вопросе – Chanti

+0

, предполагая, что время события находится в utc, просто установите CURRENT_DATE в utc вместо eventtime в CET: SELECT [...] WHERE eventtime> CURRENT_DATE в часовом поясе 'UTC' – byMike

ответ

1

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

Но одна проблема очевидна: есть индекс для столбца eventtime, но поскольку запрос работает с функцией над этим столбцом, индекс не может использоваться.

eventtime in time zone 'UTC' > CURRENT_DATE 

Либо индекс должен быть отброшен и воссозданы с этой функцией или запрос должен быть переписан.

воссоздают индекс (пример):

CREATE INDEX ON t_el_eventlog (timezone('UTC'::text, eventtime)); 

(это то же самое, как eventtime in time zone 'UTC')

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

Я подозреваю, что источник не имеет большого распространения, не имея очень разных значений. В этом случае падение индекса на SourceId И сбросив индекс на eventtime с созданием нового индекса по eventtime и SourceId может быть идея:

CREATE INDEX ON t_el_eventlog (timezone('UTC'::text, eventtime), sourceid); 

Это то, что теория говорит нам.Я провел несколько тестов по этому поводу, стол с примерно 10 миллионами строк, распределение событий в течение 36 часов и только 20 различных исходников (1..20). Распределение очень случайное. Лучшие результаты были в индексе за время события, sourceid (без индекса функции) и при настройке запроса.

CREATE INDEX ON t_el_eventlog (eventtime, sourceid); 
-- make sure there is no index on source id. we need to force postgres to this index. 

-- make sure, postgres learns about our index 
ANALYZE; VACUUM; 

-- use timezone function on current date (guessing timezone is CET) 
SELECT * FROM t_el_eventlog 
WHERE eventtime > timezone('CET',CURRENT_DATE) AND sourceid = 14; 

С таблицей, имеющей 10'000'000 строк, этот запрос возвращает мне около 500 000 рядов всего в 400 мс. (вместо 1400 до 1700 во всех других комбинациях).

Поиск наилучшего соответствия между индексами и запросом - это квест. Я предлагаю некоторые исследования, рекомендация является http://use-the-index-luke.com


это то, что план запроса выглядит с последним подходом:

Index Only Scan using evlog_eventtime_sourceid_idx on evlog (cost=0.45..218195.13 rows=424534 width=0) 
    Index Cond: ((eventtime > timezone('CET'::text, (('now'::cstring)::date)::timestamp with time zone)) AND (sourceid = 14)) 

, как вы можете видеть, это идеальный матч ...

+0

большое спасибо ..... это действительно очень быстро – Chanti

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

  • Нет связанных вопросов^_^