PostgreSQL:性能调优查询

Posted

技术标签:

【中文标题】PostgreSQL:性能调优查询【英文标题】:PostgreSQL: Performance Tuning a Query 【发布时间】:2021-10-11 07:58:04 【问题描述】:

我有一个如下表:

表名称:Table_A

A_ID A_Name
21 XYZ
22 IJK

表名称:Table_S1

S_ID S_Name A_ID
123 ABC123 21
124 PQR321 22

表名称:Table_S2

S_ID S2_Date_1 S2_Date_2
123 01/01/2015 02/04/2016
124 01/01/2021 02/04/2018
123 NULL 02/04/2019
124 01/01/2017 NULL

Table_A 和 Table_S1 有主键,而 Table_S2 没有主键。

Table_S1.A_ID --> 引用到 --> Table_A 的主键 A_ID

Table_S2.S_ID --> 引用到 --> Table_S1 的主键 S_ID

Table_S1 表中大约有 400,000 条记录,Table_S1 中的每条记录有 120 条来自 Table_S2 的记录。这意味着 Table_S2 是一个包含大约 4800 万条记录的巨大表。

我需要使用如下 2 个不同的查询分别从 Table_S2 的 S2_Date_1 和 S2_Date_2 列中获取年份。

SELECT DISTINCT EXTRACT(YEAR FROM s2.S2_Date_1)
  FROM Table_S2 s2, Table_S1 s1, Table_A a
 WHERE s2.S_ID = s1.S_ID
   AND s1.A_ID = a.A_ID
   AND s1.B_ID = b.B_ID
   AND a.A_Name = 'IJK';

如果我按 A_ID 分组,记录如下:

A_ID Count_of_Table_S1 Count_of_Table_S2
21 100,000 12,000,000
22 150,000 18,000,000
23 90,000 10,800,000

Table_S2 上没有分区。从这些数百万条记录中获取所有年份大约需要 1 分钟,我的要求是在一秒钟内获取它们。这有可能做到这一点吗? 谁能建议一个最好的方法来做到这一点?

提前致谢。

【问题讨论】:

请显示EXPLAIN (ANALYZE, BUFFERS)查询的输出,最好在设置track_io_timing = on之后。 您似乎不需要连接表的任何列,将古老的隐式连接重写为 EXISTS 条件可能会提高性能。 您将无法在一秒钟内动态汇总那么多记录。使用物化视图。 【参考方案1】:

你有很多行要总结。可靠地将此时间缩短到一秒可能是不可能的。

您可以尝试将存储的生成列放在Table_S2 上,然后对其进行索引。

ALTER TABLE Table_S2
 ADD COLUMN S2_Date1_Year 
            GENERATED ALWAYS AS EXTRACT(YEAR FROM s2.S2_Date_1)
            STORED;

这给了你专栏。那么

ALTER TABLE TABLE_S2 ADD INDEX year_by_sid (S_ID, S2_Date1_Year);

添加索引。然后将您的查询更改为

SELECT DISTINCT s2.S2_Date1_Year ...

您的查询可能会更快,但不确定:它不必重新计算每一行的年份。

您可能想要一个物化视图。

CREATE MATERIALIZED VIEW View_S2_Year AS
SELECT DISTINCT S_ID, EXTRACT(YEAR FROM s2.S2_Date_1) AS S2_Date1_Year
  FROM Table_S2;

CREATE INDEX year_by_sid ON View_S2_Year (S_ID, S2_Date1_Year);

然后加入 View_S2_Year 而不是 Table_S2。

注意:您需要不时刷新视图以使其与基表同步。在对基表进行更改后,其内容将是陈旧的,直到您刷新它为止。

REFRESH MATERIALIZED VIEW View_S2_Year;

【讨论】:

非常感谢大家。我会尝试这些方式,看看我是否可以让它像你提到的那样简单。将再次在这里分享结果。 :)

以上是关于PostgreSQL:性能调优查询的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL on Azure.cn : 性能测试及调优

Hive 查询性能调优

性能调优 SQL - 如何?

MySQL性能调优(软调优)

性能调优一次监控数据错误的性能调优经历

性能调优一次监控数据错误的性能调优经历