对于(每组许多行)中相对较少的不同值group_id
-似乎是您的情况:
3e6行/少于500个不同的group_id
为了快速实现,您需要索引跳过扫描(又称宽松索引扫描)。在Postgres 12之前尚未实现。但是您可以使用递归查询解决该限制:
更换:
select count(distinct group_id) from everything_crowberry;
带有:
WITH RECURSIVE cte AS ( (SELECT group_id FROM everything_crowberry ORDER BY group_id LIMIT 1) UNION ALL SELECT (SELECT group_id FROM everything_crowberry WHERE group_id > t.group_id ORDER BY group_id LIMIT 1) FROM cte t WHERE t.group_id IS NOT NULL ) SELECT count(group_id) FROM cte;
我使用count(group_id)
而不是稍微快一点的方法count(*)
来方便地NULL
从最终递归中消除一个值-因为count(
仅计算非空值。
此外,是否group_id
可以为无关紧要NULL
,因为无论如何您的查询都不会将其计算在内。
可以使用您已经拥有的索引:
CREATE INDEX everything_crowberry_group_id ON everything_crowberry(group_id);
有关:
优化GROUP BY查询以检索每个用户的最新行
对于相对许多不同的值group_id
(每组几排) -或对小表-平原DISTINCT
会更快。通常,在子查询中完成时最快,这与添加子句相反count()
:
SELECT count(group_id) -- or just count(*) to include possible NULL value FROM (SELECT DISTINCT group_id FROM everything_crowberry) sub;