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 DISTINCT
là 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 BY
nhanh 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_id
chỉ 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 VIEW
gấp user_id
mỗ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 time
là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.