查询性能 Postgresql
Posted
技术标签:
【中文标题】查询性能 Postgresql【英文标题】:Query performance Postgresql 【发布时间】:2021-07-01 12:58:42 【问题描述】:我们制作了一个控制台应用程序,它将更新表 b 上的 y 列。在服务器上运行这个查询,它很慢,我不知道为什么。表 t 大小为 21 GB,表 l 大小为 13 GB。
SELECT DISTINCT a.x,
a.y
FROM a
JOIN b ON a.x = b.x
-- x is uuid that we use on both tables
WHERE b.y IS NULL
AND a.y IS NOT NULL
LIMIT 500;
到目前为止我尝试过的是;
像这样在两个表上使用 where 语句创建索引
创建索引 idx_name 在 b(x) 上 其中(y 为 NULL);
创建索引 idx_name 在 (x) 上 其中 (y IS NOT NULL);
使用 group_by 而不是 distinct
尝试将最小的表连接到更大的表
你能帮帮我吗?
谢谢。
【问题讨论】:
请edit您的问题并添加使用explain (analyze, buffers, format text)
生成的execution plan(不是只是一个“简单”解释)为formatted text,并确保保留计划的缩进。粘贴文本,然后将```
放在计划前一行和计划后一行。
添加执行计划。根据您的描述:您似乎没有尝试实现Index Only Scan
。在CREATE INDEX
中查找选项INCLUDE
。我想CREATE INDEX idx_name on a(x) INCLUDE (y) WHERE (y IS NOT NULL)
可以做到这一点
解释分析也花费了太多时间来返回结果 - 从 1 小时开始它仍在尝试
【参考方案1】:
尝试创建这两个多列covering indexes。
CREATE INDEX y_x_index ON a(y,x);
CREATE INDEX x_y_index ON b(x,y);
我猜第一个索引会对这些事情有所帮助:
-
正在查找
a.y IS NOT NULL
行。
检索a.x
以用于加入
处理 SELECT DISTINCT 重复数据删除。索引的顺序适当,仅用于扫描。
无需查看主表,而是使用索引(这就是覆盖的意思)。
第二个索引会有所帮助
-
正在检索
b.x
以用于加入。
正在寻找b.y IS NULL
。
无需查看主表,而是使用索引。
您可以尝试切换第二个索引中列的顺序,看看是否更快。
并且,专业提示:请注意,没有 ORDER BY 子句的 LIMIT 子句会授予 postgreSQL 返回不可预测(非确定性)行集的权限。如果您想要一个可预测的 500 行,请输入 ORDER BY a.y, a.x
。该子句中的列似乎颠倒了以匹配索引。 a.y
必须在索引中排在第一位,否则对于匹配 a.y IS NOT NULL
将无用。
【讨论】:
泰。我会尝试这些,但是当我在索引中使用 where 语句时,我没有让它更具体吗?我还检查了pg_stat_all_tables
,看看两个表是否有死元组,但没有,没有。以上是关于查询性能 Postgresql的主要内容,如果未能解决你的问题,请参考以下文章