SQL индекс при объединении и группировании по - PullRequest
1 голос
/ 04 мая 2020

У меня запрос, который выполняется медленно. Я почти уверен, что узким местом является последовательное сканирование в плане, поэтому я хотел бы создать соответствующие индексы и / или изменить порядок своего запроса, чтобы улучшить его.

Вот мой запрос (и Вот скрипка со схемой и тестовыми данными ):

SELECT conversations.id, max(messages.timestamp) as latest_message FROM
    conversations JOIN messages on conversations.id = messages.cid
    GROUP BY conversations.id ORDER BY latest_message;

Я создал индексы для всех задействованных столбцов и вложенные индексы для cid и timestamp в обоих направлениях, все безрезультатно. Остается последовательное сканирование:

 Sort  (cost=31.31..31.56 rows=100 width=12)
   Sort Key: (max(messages."timestamp"))
   ->  HashAggregate  (cost=26.99..27.99 rows=100 width=12)
         Group Key: conversations.id
         ->  Hash Join  (cost=3.25..21.99 rows=1000 width=12)
               Hash Cond: (messages.cid = conversations.id)
               ->  Seq Scan on messages  (cost=0.00..16.00 rows=1000 width=12)
               ->  Hash  (cost=2.00..2.00 rows=100 width=4)
                     ->  Seq Scan on conversations  (cost=0.00..2.00 rows=100 width=4)

Как мне улучшить этот запрос и / или какие индексы можно построить, чтобы исправить это последовательное сканирование?

1 Ответ

2 голосов
/ 04 мая 2020

Вам не нужно join:

SELECT m.cid, max(m.timestamp) as latest_message
FROM messages m 
GROUP BY m.cid
ORDER BY latest_message;

Это должно быть в состоянии использовать индекс для messages(cid, timestamp desc). Однако, это может быть быстрее записать это как:

SELECT DISTINCT ON (m.cid) m.*
FROM messages m
ORDER BY m.cid, m.timestamp DESC;

с тем же индексом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...