You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化PostgreSQL查询速度?现有查询耗时约26ms

优化PostgreSQL推荐人统计查询的方案

当前查询语句

SELECT
    referrer_id, count(id) as referrals_count
FROM users
WHERE referrer_id != 0
GROUP BY referrer_id
order by referrals_count desc
limit 10;

执行计划分析(翻译后)

执行计划显示:PostgreSQL对users表执行顺序扫描,随后进行分组聚合操作,接着按referrals_count降序排序,最后返回前10条结果。未使用任何已创建的索引,这是因为优化器判断在当前数据分布下,全表扫描的成本低于索引扫描。

优化方案

1. 创建覆盖索引

如果表中referrer_id = 0的记录占比不低,创建包含查询所需字段的覆盖索引可以避免全表扫描:

-- PostgreSQL 11及以上版本
CREATE INDEX idx_users_referrer_id_include ON users(referrer_id) INCLUDE(id);

-- 低版本PostgreSQL(<11),将id加入索引键
CREATE INDEX idx_users_referrer_id_id ON users(referrer_id, id);

覆盖索引仅包含referrer_id和id字段,PostgreSQL可以直接从索引中获取数据完成统计,无需回表查询原数据。

2. 更新统计信息

确保PostgreSQL拥有最新的表统计数据,帮助优化器做出更合理的执行计划选择:

ANALYZE users;

3. 使用物化视图预计算结果

如果业务允许非实时统计,物化视图是最优方案——提前计算好聚合结果,查询时直接读取预计算数据:

-- 创建物化视图
CREATE MATERIALIZED VIEW mv_referral_top_counts AS
SELECT
    referrer_id, count(id) as referrals_count
FROM users
WHERE referrer_id != 0
GROUP BY referrer_id;

-- 为物化视图创建排序索引,加速取前10的查询
CREATE INDEX idx_mv_referrals_desc ON mv_referral_top_counts(referrals_count DESC);

-- 需要更新数据时,刷新物化视图
REFRESH MATERIALIZED VIEW mv_referral_top_counts;

之后查询直接从物化视图获取:

SELECT referrer_id, referrals_count
FROM mv_referral_top_counts
ORDER BY referrals_count DESC
LIMIT 10;

4. 评估当前性能合理性

15万行数据耗时26ms本身属于可接受的范围,如果业务对这个延迟没有更高要求,无需额外优化。若追求极致性能,优先考虑物化视图方案。

内容的提问来源于stack exchange,提问作者DeFaNJI

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 19:51:00