在Postgres中加速慢速SELECT DISTINCT查询的解决方案

oro*_*aki 29 sql database postgresql database-optimization

查询基本上是:

SELECT DISTINCT "my_table"."foo" from "my_table" WHERE...
Run Code Online (Sandbox Code Playgroud)

我假装我100%肯定DISTINCT查询的部分是它运行缓慢的原因,我省略了其余的查询以避免混淆,因为它是我主要关注的不同部分的缓慢(不同的是永远是缓慢的来源).

该表有250万行数据.该DISTINCT 是需要在这里没有列出的目的(因为我不想回修改后的查询,而是让不同的查询,而只是一般的信息运行在较快的DBMS的水平,如果可能的话).

如何在DISTINCT不改变SQL的情况下更快地运行(特别是使用Postgres 9)(即,我无法改变此SQL,但是可以在数据库级别优化某些内容)?

小智 31

通常情况下,您可以distinct通过使用group by替代方法来更快地运行此类查询:

select my_table.foo 
from my_table 
where [whatever where conditions you want]
group by foo;
Run Code Online (Sandbox Code Playgroud)

  • 问题是......为什么这会使查询更快? (8认同)
  • 谢谢你杰出的杰克!交换SELECT DISTINCT for GROUP BY将我的特定查询的运行时间从649ms减少到87ms,几乎快了7.5倍.我的INNER JOIN位于一个包含~30,000行(我想要匹配的行)的表和另一个包含~322,000行的连接表之间(我用它来过滤第一行).我已经为我的INNER JOIN和单个WHERE子句的两侧使用的所有列添加了索引,因此我希望找到另一个有助于加快查询的优化,这在这种特殊情况下非常有效. (6认同)
  • 这对我来说是个很好的解决方案.我最初认为是大偏移使我的查询运行缓慢,但在从DISTINCT切换到GROUP BY后,它们的运行速度提高了20倍.谢谢! (4认同)
  • @IoanAlexandruCucu [这个答案](/sf/answers/3208350841/)可能包含一些提示。 (2认同)

ant*_*oft 19

您的DISTINCT导致它对输出行进行排序以查找重复项.如果在查询选择的列上放置索引,则数据库可能能够以索引顺序读取它们并保存排序步骤.很多将取决于查询的细节和所涉及的表 - 你说"你知道问题是与DISTINCT"真的限制了可用答案的范围.

  • 仅靠索引是不够的.我的不同列上有一个索引,但查询仍需要几分钟才能搜索800万行以查找4个不同的值. (7认同)
  • 我知道它限制了答案的范围,这就是我这样做的原因。我只在寻找在数据库级别发生的答案,这就是您给我的(+1)。 (2认同)
  • 请参阅http://stackoverflow.com/a/14732410/32453,将选择的不同查询放在子查询中,然后对我有用的计数进行计数。 (2认同)

man*_*iek 7

您可以尝试增加work_mem设置,具体取决于您的数据集的大小.它可能导致将查询计划切换为散列聚合,这通常更快.

但在全球范围内设置太高之前,请先阅读它.您可以轻松地炸毁您的服务器,因为该max_connections设置充当此数字的乘数.

这意味着如果您设置work_mem = 128MB并设置max_connections = 100(默认值),则应该具有超过12.8GB的RAM.你实际上是告诉服务器它可以使用那么多来执行查询(甚至不考虑Postgres使用的任何其他内存或其他).