Anda mungkin tidak ingin mendengar ini, tetapi opsi terbaik untuk mempercepat SELECT DISTINCTadalah menghindari DISTINCT untuk memulainya. Dalam banyak kasus (tidak semua!) Dapat dihindari dengan desain database yang lebih baik atau pertanyaan yang lebih baik.
Terkadang, GROUP BYlebih cepat, karena dibutuhkan jalur kode yang berbeda.
Dalam kasus khusus Anda , sepertinya Anda tidak bisa menyingkirkannya DISTINCT. Tetapi Anda dapat mendukung kueri dengan indeks khusus jika Anda memiliki banyak pertanyaan seperti itu:
CREATE INDEX foo ON events (project_id, "time", user_id);
Menambahkan user_idhanya berguna jika Anda hanya dapat memindai indeks saja . Ikuti tautan untuk detailnya. Akan menghapus Pemindaian Tumpukan Bitmap yang mahal dari paket kueri Anda, yang menghabiskan 90% waktu permintaan.
EXPLAINOutput Anda memberi tahu saya bahwa kueri harus memadatkan 2.491 pengguna yang berbeda dari setengah juta baris yang cocok. Ini tidak akan menjadi super cepat, apa pun yang Anda lakukan, tetapi ini bisa jauh lebih cepat.
Jika interval waktu dalam kueri Anda selalu sama, MATERIALIIZED VIEWlipat user_idper (project_id, <fixed time intervall>)akan jauh. Tidak ada kesempatan di sana dengan interval waktu yang bervariasi. Mungkin Anda bisa setidaknya melipat pengguna per jam atau unit waktu minimum lainnya, dan itu akan membeli kinerja yang cukup untuk menjamin overhead yang cukup besar.
Nitpick:
Kemungkinan besar, predikat pada "time"seharusnya adalah:
AND "time" >= '2015-01-11 8:00:00'
AND "time" < '2015-02-10 8:00:00';
Selain:
Jangan gunakan timesebagai pengidentifikasi. Ini adalah kata yang dilindungi undang - undang dalam SQL standar dan tipe dasar dalam Postgres.