如何知道查询| PostgreSQL 11中是否使用了任何索引?

如何知道查询| PostgreSQL 11中是否使用了任何索引?,sql,postgresql,sql-execution-plan,postgresql-performance,Sql,Postgresql,Sql Execution Plan,Postgresql Performance,我有点困惑,需要一些建议。我使用postgresql11数据库。我有这么简单的sql语句: SELECT DISTINCT "CITY", "AREA", "REGION" FROM youtube WHERE "CITY" IS NOT NULL AND "AREA" IS NOT NULL AND "REGION" IS NOT NULL youtube我在sql语句中使用的表有2500万条记录。我认为这就是为什么查询需要15-17秒才能完成的原因。对于我使

我有点困惑,需要一些建议。我使用
postgresql11
数据库。我有这么简单的sql语句:

SELECT DISTINCT "CITY", "AREA", "REGION"
    FROM youtube
WHERE
    "CITY" IS NOT NULL
AND
    "AREA" IS NOT NULL
AND
    "REGION" IS NOT NULL
youtube
我在sql语句中使用的表有2500万条记录。我认为这就是为什么查询需要15-17秒才能完成的原因。对于我使用该查询的web项目,它太长了。我正在努力加快请求的速度

我为youtube表创建了这样的索引:

CREATE INDEX youtube_location_idx ON public.youtube USING btree ("CITY", "AREA", "REGION");
在这一步之后,我再次运行查询,但它需要相同的时间来完成。似乎查询不使用索引。如何知道查询中是否使用了索引

解释分析返回:

你通过跑步回答了标题中的问题。查询计划显示使用了哪些索引以及如何使用。有关详细信息,请参阅手册中的章节

至于为什么查询使用顺序扫描而没有索引:2500万行,
2992781行被删除
。您正在获取
24709900行
,这几乎是所有行

这永远不会很快。
这永远不会使用索引

使用索引只对所有行中的一小部分有意义。否则只会增加额外的成本。根据多个共同因素,PASGRESS查询计划器开始考虑BTAR索引,用于所有行或更少的5%左右。相关的:

好的,如果您的表行比
SELECT
列表中的三列宽得多,那么如果您只从中获取索引扫描,则部分覆盖索引可能会有所帮助。同样,需要满足一些先决条件。而且每个索引都有存储和维护成本


旁白:声明了一条注释,无法索引空值。这是不正确的,可以为空值编制索引。没有其他值那么有效,但没有多大区别。也与手头的案件无关。

我想你可以在这方面使用索引。比如:

SELECT "CITY", "AREA", "REGION"
FROM (SELECT DISTINCT ON ("CITY", "AREA", "REGION") "CITY", "AREA", "REGION"
      FROM youtube
      ORDER BY "CITY", "AREA", "REGION"
     ) car
WHERE "CITY" IS NOT NULL AND
      "AREA" IS NOT NULL AND
      "REGION" IS NOT NULL;
这应该使用
(“城市”、“地区”、“地区”)
上的索引来进行
选择DISTINCT
——这可能是一个昂贵的查询操作


也就是说,查询将返回大量数据。因此,即使使用索引,总体性能也不会有明显改善。

我知道PostgreSQL中有四种扫描类型

顺序扫描:不使用索引

索引扫描:搜索索引,然后搜索表

仅索引扫描:仅搜索索引,不扫描实际表

位图堆扫描:在索引扫描和顺序扫描之间


结果的第三行(seq scan)显示它按顺序扫描整个表。所以您没有使用索引。

它没有使用索引。它正在对表进行全表扫描(Seq-Scan)。看起来是这样的。那么,我如何告诉PostgreSQL 11数据库使用我创建的特定索引呢?它可能永远不会使用该索引,而优化器会选择执行完整的表扫描。空值不会被索引,因此刚才构建的索引不一定会辅助NOTNULL。读取表中存储的记录,主键是什么?如果Area、区域等与主键无关,则应该考虑区域、区域和代码的单独表,并只将它们的ID存储在主表中,外键。谢谢这些信息。在我的情况下,你对分区有什么看法?@NurzhanNogerbek:分区对你没有帮助。快速存储、充足的RAM(用于重复调用)以及与服务器的快速连接都会有所帮助。(通过线路传输数据可能是这里的瓶颈。)是否需要获取几乎所有的行?这是这里的核心问题。好吧,如果我将特定值设置为列
CITY
AREA
REGION
,分区还是有帮助的?分区对这个查询没有帮助。时期不确定“为列设置特定值”是什么意思。问题是:您需要检索24M行吗?为什么
是不同的
?通过
为列设置特定值
我的意思是我们可以使用这样的查询:
从youtube上选择不同的“城市”、“地区”、“地区”,其中“城市”=“阿尔珀顿”和“地区”=“布伦特”和“地区”=“温布利”
。我认为在这种情况下分区可能是有用的。听了你的话,我感到困惑。我还注意到,没有
DISTINCT
的查询速度更快。所以我决定放弃
DISTINCT
命令。