Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL:如何加快这个select distinct查询的速度?_Sql_Postgresql - Fatal编程技术网

SQL:如何加快这个select distinct查询的速度?

SQL:如何加快这个select distinct查询的速度?,sql,postgresql,Sql,Postgresql,我目前正在将一个应用程序从Oracle移植到PostgresSQL。我对Oracle也有同样的问题,现在似乎是尝试解决这个问题的好时机 无论如何,我有一个大约2亿行的表,每天增加10万行,如下所示: create table T1( id bigserial primary key, a integer, b char(5), c char(2), ); CREATE INDEX I ON T1(A,B,C); 现在,我需要知道唯一的A,B,C值的集合是什么,所以我们看到一个

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

无论如何,我有一个大约2亿行的表,每天增加10万行,如下所示:

create table T1(
  id bigserial primary key,
  a integer,
  b char(5),
  c char(2),
);
CREATE INDEX I ON T1(A,B,C);
现在,我需要知道唯一的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 table T1(
  id bigserial primary key,
  a integer,
  b char(5),
  c char(2),
);
CREATE INDEX I ON T1(A,B,C);
索引已经加快了速度,因为它允许索引扫描而不是表扫描

此查询通常需要大约一分钟的时间,返回的行数少于100行。我想大概需要一毫秒。我认为最简单的解决方案是创建一个新表来跟踪这些值,然后在向T1添加新记录时,只需检查其中的a、B、C元组,如果缺少,则添加一个新记录,这是一个极其罕见的事件。这看起来很麻烦,一定有比使用两张桌子更好的方法

正如人们所预料的那样,使用分组技巧并没有多大帮助,因为它仍然在以任何一种方式扫描整个索引

查询计划如下所示:


我们可以看到,T2连接中的表达式有很大的帮助,因为它过滤了T1上的大块索引,正如预期的那样。

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

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

通常,使用您正在筛选的表启动会更快。您正在T2.NAME='FOO'上进行筛选,并且正在使用内部联接

从T2开始,连接到T1,然后连接到T3

在T3.ID上的T3上放置一个索引,在T1.A上放置另一个索引


这将限制查询必须查找的行数。对于T2中名称为'FOO'的记录,它将仅链接到T3和T1。因此,大大减少了查询的总工作量。

您是否也可以共享查询计划,因为您认为连接是不相关的,这一假设可能不成立。如果看到实际的查询计划,那么可能会得到更好的答案。添加了查询计划。你可以看到T2和T3非常小。T2.ID和T3.ID是主键。这也是测试数据,T1大约有45M行。您也尝试过选项吗?没有尝试过物化视图。看起来可行,因为我可以每天重建一次或每小时重建一次以获取新元组。是的,请向我们展示你的解释分析、缓冲区选择…这是一堆毫无帮助的随机建议:在T3.ID上的T3上放置索引-它已经是索引了-只查看索引扫描,T1.a上的另一个索引-无用,它已经被索引了,我们在A、B、C上有索引,所以我们不需要在A上有单独的索引。您应该检查您的查询是否使用了您认为它正在使用的索引。我认为你的这种想法可能有错误。确保所有联接都使用索引。