PostgreSQL медленный счет / группа / дата_трикс микс - PullRequest
0 голосов
/ 30 января 2019

У меня есть следующий запрос:

select count(*), date_trunc('day', updated_at) from test group by date_trunc('day', updated_at);

и при объяснении у меня есть следующее:

GroupAggregate  (cost=213481.83..223749.85 rows=245009 width=8)
  ->  Sort  (cost=213481.83..215883.63 rows=960720 width=8)
      Sort Key: (date_trunc('day'::text, updated_at))
  ->  Index Only Scan using updatedat on test  (cost=0.00..91745.26 rows=960720 width=8)

Как вы можете видеть, это имеет высокую стоимость и время запросасоставляет 6231,58 мс.

Есть ли способ улучшить это?Какой индекс должен быть наилучшим для создания этого типа смеси count / group / date_trunc.

1 Ответ

0 голосов
/ 31 января 2019

Если в вашей таблице действительно 250000 разных дней, вы, вероятно, не сможете добиться большего, чем этот.Однако увеличение work_mem ускорит сортировку.

Если, однако, число различных дней значительно меньше, проблема заключается в том, что PostgreSQL не может оценить распределение результатов date_trunc, если толькоВы создаете индекс:

CREATE INDEX ON test (date_trunc('day', updated_at));

Если updated_at равен timestamp without time zone, это будет работать нормально.Для timestamp with time zone вам необходимо указать часовой пояс, поскольку в противном случае результат будет зависеть от часового пояса сеанса, что делает его непригодным для индекса:

CREATE INDEX ON test (date_trunc('day', updated_at AT TIME ZONE 'UTC'));

Тогда ANALYZEв таблице, увеличьте work_mem и посмотрите, сможете ли вы получить хэш-агрегат вместо сортировки.

Конечно, если вам нужно использовать AT TIME ZONE в определении индекса, вам также придется использовать егов запросе ...

...