おそらくこれを聞きたくないでしょうが、スピードアップSELECT DISTINCT
するための 最良の選択肢はDISTINCT
、最初から避けることです。多くの場合(すべてではありません!)、より良いデータベース設計またはより良いクエリで回避できます。
場合によってGROUP BY
は、異なるコードパスを使用するため、高速になります。
では、あなたの特定のケースあなたは取り除くことができますように、それはいないようですDISTINCT
。ただし、そのようなクエリが多数ある場合は、特殊なインデックスでクエリをサポートできます。
CREATE INDEX foo ON events (project_id, "time", user_id);
追加user_id
は、これからインデックスのみのスキャンを取得する場合にのみ役立ちます。詳細については、リンクをたどってください。クエリプランの90%を消費する高価なビットマップヒープスキャンをクエリプランから削除します。
あなたのEXPLAIN
出力は、クエリは、五十万一致する行のうち、2491人の異なるユーザーを凝縮していることを私に伝えます。あなたが何をしても、これは超高速になりませんが、かなり速くなります。
クエリの時間間隔は常に同じであれば、MATERIALIIZED VIEW
折りたたみuser_id
あたりは(project_id, <fixed time intervall>)
長い道のりを行くだろう。ただし、さまざまな時間間隔でチャンスはありません。たぶん、ユーザーを少なくとも1時間あたりまたは他の最小時間単位でフォールドできれば、かなりのオーバーヘッドを保証するのに十分なパフォーマンスが得られます。
Nitpick:
おそらく、上の述語"time"
は実際にあるはずです:
AND "time" >= '2015-01-11 8:00:00'
AND "time" < '2015-02-10 8:00:00';
余談:識別子として
使用しないでくださいtime
。これは標準SQLの予約語であり、Postgresの基本型です。