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

gojuced7  于 12个月前  发布在  PostgreSQL
关注(0)|答案(3)|浏览(220)

我有点困惑,需要一些建议。我使用PostgreSQL 11数据库。我有这样一个非常简单的sql语句:

SELECT DISTINCT "CITY", "AREA", "REGION"
    FROM youtube
WHERE
    "CITY" IS NOT NULL
AND
    "AREA" IS NOT NULL
AND
    "REGION" IS NOT NULL

字符串
我在sql语句中使用的youtube表有2500万条记录。我认为这就是为什么查询需要15-17秒才能完成。对于我使用该查询的Web项目来说,它太长了。我试图加快请求。
我为youtube表创建这样的索引:

CREATE INDEX youtube_location_idx ON public.youtube USING btree ("CITY", "AREA", "REGION");


在这一步之后,我再次运行查询,但它需要同样的时间来完成。它似乎不使用索引查询。我怎么知道,如果任何索引是在查询中使用?

解析返回:x1c 0d1x

drnojrws

drnojrws1#

您通过运行EXPLAIN自己回答了标题中的问题。查询计划显示了使用哪些索引以及如何使用。有关详细信息,请参阅手册中的"Using EXPLAIN "一章。
至于为什么查询使用顺序扫描而没有索引:2500万行,992781 rows removed。你正在获取24709900 rows,这几乎是所有的行。
这永远不会很快,它只会在特殊情况下使用索引。
使用索引通常只对所有行的一小部分有意义。否则它只会增加额外的成本。根据一些辅助因素,Postgres查询规划器开始考虑对所有行的5%或更少的btree索引。相关信息:

  • 当索引扫描是更好的选择时,Postgres不使用索引

好吧,如果你的表行比SELECT列表中的三列宽得多,如果你只扫描索引,一个(部分)* 覆盖 * 索引可能会有所帮助。同样,需要满足一些先决条件。每个索引也会增加存储和维护成本。
旁白:一条评论声称NULL值无法被索引。这是不正确的,NULL值可以被索引。不像其他值那样有效,但没有太大的区别。也与手头的案例无关。

7vux5j2d

7vux5j2d2#

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

**顺序扫描:**不使用索引。
**索引扫描:**先扫描索引,再扫描表。
**只扫描索引:**只扫描索引,不扫描实际表。
**位图堆扫描:**介于索引扫描和顺序扫描之间。

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

xkftehaa

xkftehaa3#

我认为你可以用一个索引来描述它。比如:

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;

字符串
这应该对SELECT DISTINCT使用("CITY", "AREA", "REGION")上的索引--对于这个查询来说,这可能是一个开销很大的操作。
也就是说,查询将返回大量数据,因此即使使用索引也可能不会显著提高整体性能。

相关问题