Có thể bạn không muốn nghe điều này, nhưng lựa chọn tốt nhất để tăng tốc SELECT DISTINCTlà tránh DISTINCT bắt đầu. Trong nhiều trường hợp (không phải tất cả!) Có thể tránh được với thiết kế cơ sở dữ liệu tốt hơn hoặc truy vấn tốt hơn.
Đôi khi, GROUP BYnhanh hơn, bởi vì nó có một đường dẫn mã khác.
Trong trường hợp cụ thể của bạn , có vẻ như bạn không thể thoát khỏi DISTINCT. Nhưng bạn có thể hỗ trợ truy vấn bằng một chỉ mục chuyên biệt nếu bạn có nhiều truy vấn loại đó:
CREATE INDEX foo ON events (project_id, "time", user_id);
Thêm user_idchỉ hữu ích nếu bạn nhận được quét chỉ mục từ điều này. Theo liên kết để biết chi tiết. Sẽ xóa Bitmap Heap Scan đắt tiền khỏi gói truy vấn của bạn, việc này tiêu tốn 90% thời gian truy vấn.
EXPLAINĐầu ra của bạn cho tôi biết rằng truy vấn phải thu được 2.491 người dùng khác nhau trong số nửa triệu hàng phù hợp. Điều này sẽ không trở nên siêu nhanh, bất kể bạn làm gì, nhưng nó có thể nhanh hơn đáng kể.
Nếu các khoảng thời gian trong các truy vấn của bạn luôn giống nhau, thì việc MATERIALIIZED VIEWgấp user_idmỗi lần (project_id, <fixed time intervall>)sẽ đi một chặng đường dài. Không có cơ hội ở đó với khoảng thời gian khác nhau, mặc dù. Có lẽ bạn ít nhất có thể gấp người dùng mỗi giờ hoặc một số đơn vị thời gian tối thiểu khác, và điều đó sẽ mua đủ hiệu suất để đảm bảo chi phí đáng kể.
Nitpick:
Rất có thể, các vị từ trên "time"thực sự nên là:
AND "time" >= '2015-01-11 8:00:00'
AND "time" < '2015-02-10 8:00:00';
Ngoài ra:
Không sử dụng timelàm định danh. Đó là một từ dành riêng trong SQL tiêu chuẩn và một loại cơ bản trong Postgres.