postgresql - 提高选择查询的性能
问题描述
我有这个物化视图,它聚合来自多个表的数据,这些表在我的应用程序中存储有关统计数据的信息。目前,此视图包含大约 800.000 条记录。问题是这个查询运行速度很慢(大约 1.5 秒)并且不能满足客户的需求。有什么方法可以提高它的性能吗?我正在使用 PostgreSQL 9.6。
我试图创建索引。但这无济于事。
CREATE INDEX t1 ON statistic_basic_view (active, visible, removed, draft, id, name, object_type, is_paid, company_name);
CREATE INDEX t2 ON statistic_basic_view (company_name, is_paid, object_type, name, id, draft, removed, visible, active);
CREATE INDEX t3 ON statistic_basic_view (company_name, is_paid, object_type, name, id);
CREATE INDEX t4 ON statistic_basic_view (draft, removed, visible, active);
CREATE INDEX t5 ON statistic_basic_view (active, visible, removed, draft);
CREATE INDEX t6 ON statistic_basic_view (id, name, object_type, is_paid, company_name);
CREATE INDEX t8 ON statistic_basic_view (active, visible, removed, draft, id, name, object_type, is_paid, company_name);
CREATE INDEX t9 ON statistic_basic_view ((active AND visible AND (NOT removed) AND (NOT draft)));
CREATE INDEX t10 ON statistic_basic_view (((NOT draft) AND (NOT removed) AND active = true AND visible = true));
询问:
SELECT id,
name,
object_type,
is_paid,
company_name,
SUM(CASE
WHEN type = 'COMPARE'
AND service_type IN ('GG_WEB') THEN 1
ELSE 0
END) AS compare_count,
SUM(CASE
WHEN type = 'EXPORT'
AND service_type IN ('GG_WEB') THEN 1
ELSE 0
END) AS export_count,
SUM(CASE
WHEN type = 'VIEW'
AND service_type IN ('GG_WEB') THEN 1
ELSE 0
END) AS view_count,
SUM(CASE
WHEN type = 'REMEMBER'
AND service_type IN ('GG_WEB') THEN 1
ELSE 0
END) AS remember_count,
SUM(CASE
WHEN type = 'SEARCH'
AND service_type IN ('GG_WEB') THEN 1
ELSE 0
END) AS search_count,
SUM(CASE
WHEN type = 'MAIL'
AND service_type IN ('GG_WEB') THEN 1
ELSE 0
END) AS mail_count
FROM statistic_basic_view
WHERE active = TRUE
AND visible = TRUE
AND removed = FALSE
AND draft = FALSE
GROUP BY id,
name,
object_type,
is_paid,
company_name
ORDER BY view_count DESC,
id ASC
limit 15;
解释分析:
Limit (cost=74204.47..74204.50 rows=15 width=130) (actual time=1420.542..1420.545 rows=15 loops=1)
-> Sort (cost=74204.47..74600.55 rows=158432 width=130) (actual time=1420.540..1420.542 rows=15 loops=1)
Sort Key: (sum(CASE WHEN ((type = 'VIEW'::text) AND ((service_type)::text = 'GG_WEB'::text)) THEN 1 ELSE 0 END)) DESC, id
Sort Method: top-N heapsort Memory: 28kB
-> HashAggregate (cost=68733.10..70317.43 rows=158432 width=130) (actual time=1420.539..1420.542 rows=8988 loops=1)
Group Key: id, name, object_type, is_paid, company_name
-> Seq Scan on statistic_basic_view (cost=0.00..24950.65 rows=761434 width=94) (actual time=0.023..249.851 rows=762118 loops=1)
Filter: (active AND visible AND (NOT removed) AND (NOT draft))
Rows Removed by Filter: 30047
Planning time: 0.665 ms
Execution time: 1420.545 ms
解决方案
没有索引可以帮助您进行此查询。
没有一个WHERE
条件是选择性的,你不能使用索引来加速GROUP BY
有那么多组,你不能使用索引进行排序(因为在此之前有一个不同标准的分组)。
您应该做的是在您的物化视图顶部(或直接在基表顶部)创建另一个物化视图,该视图具有预先计算的结果并定期刷新。这会为您提供稍微陈旧的数据,但速度很快。
推荐阅读
- kubernetes - Kafka/Kubernetes 和 Autoscale
- sonarqube - Sonarqube 更新 6.7 到 7.9 - 空表
- node.js - 我正在尝试将重置令牌链接传递给 ejs 引擎,但是当发送的邮件锚标记未显示 href 属性时
- oracle - 如何使用 Oracle Apex LDAP 身份验证方案获取用户详细信息
- python - 如何修复 AttributeError:模块“tensorflow”没有属性“ConfigProto”
- javascript - 预期标识符 - 非 ES6 版本的脚本在 IE11 中给出错误
- python - 如何将 24 帧编码为一张 24 位 RGB 图像?
- google-apps-script - 如何在 Google Drive API 中获取所有用户的编辑权限
- php - 致命错误:未捕获的错误:找不到类“ClientRepository”
- scilab - Scilab - 查找具有不同索引的随机生成数字的平均值