如何在PostgreSQL中使用DISTINCT加快查询速度?

时间:2018-12-06 03:33:41

标签: sql postgresql indexing distinct

如您所见,我有一个非常简单的SQL语句:

SELECT DISTINCT("CITY" || ' | '  || "AREA" || ' | ' || "REGION") AS LOCATION
FROM youtube

我在查询中使用的youtube表有大约2500万条记录。该查询需要很长时间才能完成(约25秒)。我正在尝试加快请求的速度。

我创建了如下所示的索引,但是我的上一级查询仍然需要相同的时间才能完成。我做错了什么?顺便说一句,在我的情况下使用“分区”更好吗?

CREATE INDEX location_index ON youtube ("CITY", "AREA", "REGION")

EXPLAIN返回:

Unique (cost=5984116.71..6111107.27 rows=96410 width=32)
-> Sort (cost=5984116.71..6047611.99 rows=25398112 width=32)
   Sort Key: ((((("CITY" || ' | '::text) || "AREA") || ' | '::text) || "REGION"))
   -> Seq Scan on youtube (cost=0.00..1037365.24 rows=25398112 width=32) 
您的脚本的

@ george-joseph QUERY PLAN

enter image description here

3 个答案:

答案 0 :(得分:5)

索引和分区都无法为您提供帮助。

由于cityarearegion之间(可能)紧密相关,因此结果行的数量将比PostgreSQL估计的少得多,因为它假定列彼此独立其他。

因此,您应该在这些列上创建扩展的统计信息,这是PostgreSQL v10中引入的一项新功能:

CREATE STATISTICS youtube_stats (ndistinct)
   ON "CITY", "AREA", "REGION" FROM youtube;

ANALYZE youtube;

现在PostgreSQL对有多少个不同的组有了更好的了解。

然后为查询提供大量内存,以便它可以将所有这些组的哈希值存储到内存中。然后,它可以使用哈希聚合而不是对行进行排序:

SET work_mem = '1GB';

您可能不需要那么多的内存;尝试找到更合理的限制。

然后尝试从George Joseph的答案中查询:

SELECT x."CITY" || ' | '  || x."AREA" || ' | ' || x."REGION" AS location
FROM (SELECT DISTINCT "CITY", "AREA", "REGION"
      FROM youtube) AS x;

答案 1 :(得分:1)

由于列上有索引, 如果您要执行以下操作,查询计划将如何?

SELECT x.city || ' | '  || x.area || ' | ' || x.region
FROM (SELECT DISTINCT city, area, region
      FROM youtube) x 

答案 2 :(得分:0)

索引应该可以提供帮助。尝试将查询编写为:

SELECT DISTINCT ON (city, area, region) "CITY" || ' | '  || "AREA" || ' | ' || "REGION") AS LOCATION
FROM youtube
ORDER BY city, area, region;

这可以利用(city, area, region)上的索引。