3

ユーザーが当社の Web サイトにアクセスしたときに、Segment.com によって作成されたanonymous_id(string) 列と(datetime) 列を含む Postgres テーブルがあります。timestamp

~5M の行があり、~1M の個別の anonymous_id があります

月ごとに見つかった個別の anonymous_ids の数を照会したいと思います。

私はこれまでのところこれを持っていますが、これは動作しますが、PSequel でタイムアウトします (数回実行して日付を制限することができます)

SELECT count(1), "month"
FROM (
    SELECT DISTINCT anonymous_id, 
    date_trunc('month', "timestamp") as "month"
    FROM pages
    -- WHERE "timestamp" between '2018-01-01' and '2018-02-01'
) as dt
GROUP BY 2
ORDER BY 2

anonymous_id と timestamp の両方にインデックスがあります

の結果EXPLAIN ANALYSE

                                                                 QUERY PLAN                                                                  
---------------------------------------------------------------------------------------------------------------------------------------------
 Sort  (cost=1667977.72..1667978.22 rows=200 width=8) (actual time=115861.803..115861.807 rows=27 loops=1)
   Sort Key: (date_trunc('month'::text, pages."timestamp"))
   Sort Method: quicksort  Memory: 26kB
   ->  HashAggregate  (cost=1667968.07..1667970.07 rows=200 width=8) (actual time=115861.763..115861.766 rows=27 loops=1)
         Group Key: (date_trunc('month'::text, pages."timestamp"))
         ->  Unique  (cost=1554502.82..1592324.57 rows=5042900 width=45) (actual time=97492.062..115468.396 rows=1158934 loops=1)
               ->  Sort  (cost=1554502.82..1567110.07 rows=5042900 width=45) (actual time=97492.060..113983.496 rows=5042900 loops=1)
                     Sort Key: pages.anonymous_id, (date_trunc('month'::text, pages."timestamp"))
                     Sort Method: external merge  Disk: 285936kB
                     ->  Seq Scan on pages  (cost=0.00..682820.25 rows=5042900 width=45) (actual time=0.088..25601.944 rows=5042900 loops=1)
 Planning time: 10.335 ms
 Execution time: 115910.353 ms
(12 rows)

現在のインデックス (以下の Thorsten Kettner によって提案された複合インデックスを含む)

Indexes:
    "pages_pkey" PRIMARY KEY, btree (id)
    "idx_anonymous_id" btree (anonymous_id)
    "idx_date_trunc_anon_id" btree (date_trunc('month'::text, timezone('UTC'::text, "timestamp")), anonymous_id)
    "idx_path" btree (path)
    "idx_timestamp" btree ("timestamp")
    "idx_url" btree (url)
    "idx_user_id" btree (user_id)
    "pages_activity_type_idx" btree (activity_type)
4

2 に答える 2

0

式で始まるインデックスが必要ですgroup by。理想的には、次のものも含まれていanonymous_idます。

CREATE INDEX idx1 ON pages( date_trunc('month', "timestamp") , anonymous_id);

句が必要な場合WHEREは、最初にその基準が必要です。

CREATE INDEX idx2 ON pages( "timestamp" , date_trunc('month', "timestamp") , anonymous_id);

Greg Viers が示したように、クエリは必要以上に複雑です。私は彼のものと一緒に行きます。必要なインデックスは、両方のクエリで同じです。

于 2018-02-02T14:23:44.943 に答える