【问题标题】:Query performance Postgresql查询性能 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;

到目前为止我尝试过的是;

  1. 像这样在两个表上使用 where 语句创建索引

    创建索引 idx_name 在 b(x) 上 其中(y 为 NULL);

    创建索引 idx_name 在 (x) 上 其中 (y IS NOT NULL);

  2. 使用 group_by 而不是 distinct

  3. 尝试将最小的表连接到更大的表

你能帮帮我吗?

谢谢。

【问题讨论】:

  • 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 小时开始它仍在尝试

标签: postgresql query-optimization


【解决方案1】:

尝试创建这两个多列covering indexes

CREATE INDEX y_x_index ON a(y,x);
CREATE INDEX x_y_index ON b(x,y);

我猜第一个索引会对这些事情有所帮助:

  1. 正在查找 a.y IS NOT NULL 行。
  2. 检索a.x 以用于加入
  3. 处理 SELECT DISTINCT 重复数据删除。索引的顺序适当,仅用于扫描。
  4. 无需查看主表,而是使用索引(这就是覆盖的意思)。

第二个索引会有所帮助

  1. 正在检索 b.x 以用于加入。
  2. 正在寻找b.y IS NULL
  3. 无需查看主表,而是使用索引。

您可以尝试切换第二个索引中列的顺序,看看是否更快。

并且,专业提示:请注意,没有 ORDER BY 子句的 LIMIT 子句会授予 postgreSQL 返回不可预测(非确定性)行集的权限。如果您想要一个可预测的 500 行,请输入 ORDER BY a.y, a.x。该子句中的列似乎颠倒了以匹配索引。 a.y 必须在索引中排在第一位,否则对于匹配 a.y IS NOT NULL 将无用。

【讨论】:

  • 泰。我会尝试这些,但是当我在索引中使用 where 语句时,我没有让它更具体吗?我还检查了pg_stat_all_tables,看看两个表是否有死元组,但没有,没有。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-06
  • 2021-08-03
  • 2013-02-17
  • 2013-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多