首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何通过查询加速大表上的计数+组?

如何通过查询加速大表上的计数+组?
EN

Stack Overflow用户
提问于 2018-02-02 13:55:26
回答 2查看 1.1K关注 0票数 3

当用户访问我们的网站时,我有一个带有anonymous_id(string)和timestamp (datetime)列的Postgres表,它们是由Segment.com创建的。

有~5M行,~1M不同的anonymous_id

我想查询每个月发现的不同anonymous_ids的数量。

到目前为止,我已经完成了这个工作,但是在PSequel中可以超时(我可以多次运行它并限制日期)

代码语言:javascript
复制
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和时间戳都有索引

EXPLAIN ANALYSE结果

代码语言:javascript
复制
                                                                 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提出的综合指数)

代码语言:javascript
复制
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)
EN

回答 2

Stack Overflow用户

发布于 2018-02-02 14:09:39

我唯一能想到的就是摆脱derived table,因为您不需要它:

代码语言:javascript
复制
SELECT count(distinct anonymous_id), date_trunc('month', "timestamp") AS "month"
FROM pages
GROUP BY date_trunc('month', "timestamp")
ORDER BY date_trunc('month', "timestamp");
票数 1
EN

Stack Overflow用户

发布于 2018-02-02 14:23:44

您需要一个以group by表达式开头的索引。理想情况下,它还包含anonymous_id

代码语言:javascript
复制
CREATE INDEX idx1 ON pages( date_trunc('month', "timestamp") , anonymous_id);

如果您想要一个WHERE子句,那么首先需要它的条件:

代码语言:javascript
复制
CREATE INDEX idx2 ON pages( "timestamp" , date_trunc('month', "timestamp") , anonymous_id);

如Greg所示,您的查询比需要的要复杂得多。我会跟他一起去。两个查询所需的索引是相同的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48584189

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档