Напевно, ви не хочете цього чути, але найкращий варіант для прискорення - SELECT DISTINCT
це уникати DISTINCT
для початку. У багатьох випадках (не у всіх!) Цього можна уникнути за допомогою кращого дизайну баз даних або кращих запитів.
Іноді, GROUP BY
швидше, тому що він займає інший шлях коду.
У вашому конкретному випадку не здається, що ви можете позбутися DISTINCT
. Але ви можете підтримати запит спеціалізованим індексом, якщо у вас є багато запитів такого типу:
CREATE INDEX foo ON events (project_id, "time", user_id);
Додавання user_id
корисно лише в тому випадку, якщо з цього ви отримаєте сканування , призначені лише для покажчиків . Докладніше перейдіть за посиланням. Видалить з плану запитів дорогий Bitmap Heap Scan , який забирає 90% часу запиту.
Ваша EXPLAIN
висновок підказує мені, що запит має стиснути 2491 різних користувачів із півмільйона відповідних рядків. Це не стане надшвидким, що б ви не робили, але це може бути значно швидше.
Якщо інтервали часу у ваших запитах завжди однакові, MATERIALIIZED VIEW
складанняuser_id
на (project_id, <fixed time intervall>)
певний шлях пройде досить довго. Немає жодного шансу з різними інтервалами часу. Можливо, ви могли б принаймні скласти користувачів на годину чи якусь мінімальну одиницю часу, і це дозволить придбати достатню продуктивність, щоб гарантувати значні витрати.
Нітпік:
Скоріш за все, предикати "time"
повинні бути:
AND "time" >= '2015-01-11 8:00:00'
AND "time" < '2015-02-10 8:00:00';
Убік:
Не використовуйте time
як ідентифікатор. Це зарезервоване слово у стандартному SQL та базовий тип у Postgres.