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

gojuced7  于 2023-11-18  发布在  PostgreSQL
关注(0)|答案(3)|浏览(262)

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

  1. SELECT DISTINCT "CITY", "AREA", "REGION"
  2. FROM youtube
  3. WHERE
  4. "CITY" IS NOT NULL
  5. AND
  6. "AREA" IS NOT NULL
  7. AND
  8. "REGION" IS NOT NULL

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

  1. 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#

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

  1. SELECT "CITY", "AREA", "REGION"
  2. FROM (SELECT DISTINCT ON ("CITY", "AREA", "REGION") "CITY", "AREA", "REGION"
  3. FROM youtube
  4. ORDER BY "CITY", "AREA", "REGION"
  5. ) car
  6. WHERE "CITY" IS NOT NULL AND
  7. "AREA" IS NOT NULL AND
  8. "REGION" IS NOT NULL;

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

相关问题