SQL:如何加快这个选择不同的查询?

时间:2017-07-13 16:18:59

标签: sql postgresql

我目前正在将应用程序从Oracle移植到PostgresSQL。我在Oracle中遇到了同样的问题,这似乎是尝试解决这个问题的好时机。

无论如何,我有一个大约200M行的表,每天增加100k行,如下所示:

create table T1(
  id bigserial primary key,
  a integer,
  b char(5),
  c char(2),
);

现在,我时不时地想知道一组独特的A,B,C值是什么,所以我们看到一个看起来像这样的查询。我认为表格连接在很大程度上与问题无关,但我要将它们包括在内以便完整。

SELECT DISTINCT A, B, C, T3.N 
     FROM T1
     JOIN T2 ON T2.ID = T1.A AND T2.NAME = 'FOO'
     JOIN T3 ON T3.ID = T2.PID

也是一个如下所示的索引:

CREATE INDEX I ON T1(A,B,C);

索引已经加速,因为它允许索引扫描而不是表扫描。

此查询通常需要大约一分钟左右,并返回少于100行。我希望它花费大约一毫秒。我认为天真的解决方案是创建一个新表只是为了跟踪这些值,然后在向T1添加新记录时只检查那里的A,B,C元组并添加一条新记录,如果它丢失了这是一个极端的罕见的事件。这似乎很麻烦,必须有一个比使用两个表更好的方法。

如果有的话,使用GROUP BY技巧并没有多大帮助,因为它仍在扫描整个索引。

查询计划如下所示:

enter image description here

我们可以看到T2连接中的表达式有很大帮助,因为它会像预期的那样在T1上过滤掉大量的索引。

1 个答案:

答案 0 :(得分:-1)

考虑使用更多索引。确保您拥有链接到数据的每种方式的索引。

例如,你链接到T2.ID上的t2。因此,请确保您只有T2.id上的索引而不是复合索引。

通常,使用您要过滤的表格加注星标会更快。您正在过滤T2.NAME =' FOO'而你正在使用内连接。

首先从T2开始,加入T1,然后加入T3。

同时在T3.ID上放置T3,在T1.A上放置另一个索引。

这将限制查询必须查找的行数。它只会链接到T2和T1,用于T2中的记录,即NAME =' FOO'。从而显着减少查询的总工作量。