Быстрее находите различные значения

#postgresql #distinct

Вопрос:

У меня есть следующая таблица (я ее упростил):

 CREATE TABLE user_action_history (
    id serial,
    user_id integer,
    page_id integer,
    ts timestamp,
    ...
);
 

Я запускаю этот запрос, чтобы узнать, к каким страницам обращался мой пользователь:

SELECT distinct page_id FROM user_action_history WHERE user_id=$id

У меня уже есть индекс (идентификатор пользователя, идентификатор страницы), и он сканирует только индекс, но это недостаточно быстро, иногда для моих 4,5-метровых строк требуется 2-3 секунды.

Я полагаю, что мог бы создать другую таблицу с уникальными значениями идентификатора пользователя, идентификатора страницы и столбца счетчика строк и поддерживать ее с помощью триггеров, но мне было интересно, есть ли у кого-нибудь более креативное решение. У меня есть postgres 9.5, который не будет обновлен в ближайшее время, так что это ограничение.

Изменить: вот как выглядит объяснение (анализ, буферы) приведенного выше запроса:

  HashAggregate  (cost=2010.74..2010.75 rows=1 width=2) (actual time=3483.189..3483.193 rows=26 loops=1)
   Group Key: page_id
   Buffers: shared hit=65 read=277
   ->  Index Only Scan using user_action_history_idx on user_action_history  (cost=0.43..1966.96 rows=17513 width=2) (actual time=29.588..3480.510 rows=15747 loops=1)
         Index Cond: (user_id = 10)
         Heap Fetches: 2142
         Buffers: shared hit=65 read=277
 Planning time: 53.465 ms
 Execution time: 3483.242 ms
 

Комментарии:

1. Достаточно ли часто пылесосят стол?

2. Пожалуйста, покажите EXPLAIN (ANALYZE, BUFFERS) , что это медленно.

3. Вот, пожалуйста, я отредактировал вопрос. Во всяком случае, я узнал о опции БУФЕРОВ, это уже кое-что.

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

5. » иногда это занимает 2-3 секунды на моих 4,5 — метровых рядах». — что здесь означает «иногда»? Означает ли это, что иногда это происходит быстро?