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

Nur*_*bek 1 sql postgresql indexing distinct

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

SELECT DISTINCT("CITY" || ' | '  || "AREA" || ' | ' || "REGION") AS LOCATION
FROM youtube
Run Code Online (Sandbox Code Playgroud)

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

我创建了一个索引,如下所示,但我的查询更高仍然需要相同的时间才能完成.我做错了什么?顺便说一下,在我的情况下使用"分区"是否更好?

CREATE INDEX location_index ON youtube ("CITY", "AREA", "REGION")
Run Code Online (Sandbox Code Playgroud)

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) 
Run Code Online (Sandbox Code Playgroud)

@ george-joseph QUERY PLAN你的剧本:

在此输入图像描述

Lau*_*lbe 5

索引和分区都不能帮助你.

因为city,arearegion被(可能)密切相关,结果行的数量将远小于PostgreSQL的估计,因为它假定列相互独立.

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

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

ANALYZE youtube;
Run Code Online (Sandbox Code Playgroud)

现在PostgreSQL可以更好地了解有多少不同的组.

然后给查询提供大量内存,以便它可以将所有这些组的哈希值放入内存中.然后它可以使用哈希聚合而不是排序行:

SET work_mem = '1GB';
Run Code Online (Sandbox Code Playgroud)

你可能不需要那么多记忆; 试验找到一个更合理的限制.

然后尝试George Joseph的回答:

SELECT x."CITY" || ' | '  || x."AREA" || ' | ' || x."REGION" AS location
FROM (SELECT DISTINCT "CITY", "AREA", "REGION"
      FROM youtube) AS x;
Run Code Online (Sandbox Code Playgroud)