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

时间:2018-12-07 03:47:04

标签: sql postgresql sql-execution-plan postgresql-performance

我有点困惑,需要一些建议。我使用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");

在此步骤之后,我再次运行查询,但是需要花费相同的时间才能完成。似乎查询不使用索引。我怎么知道查询中是否使用了索引?

EXPLAIN ANALYZE 返回: enter image description here

3 个答案:

答案 0 :(得分:3)

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

顺序扫描:不使用索引。

索引扫描:先搜索索引,然后搜索表格。

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

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

结果的第三行(seq扫描)显示它顺序扫描整个表。因此,您没有使用索引。

答案 1 :(得分:1)

您通过运行EXPLAIN自己回答了标题中的问题。查询计划显示使用哪些索引以及如何使用。有关详细信息,请参见手册中的"Using EXPLAIN"一章。

关于查询为何使用顺序扫描而没有索引的原因:2500万行,2992781 rows removed。您正在获取24709900 rows,这几乎是所有行。

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

仅对所有行的一小部分使用索引才有意义。否则,这只会​​增加额外的成本。根据许多辅助因素,Postgres查询计划器开始考虑占所有行的5%或更少的btree索引。相关:

好吧,如果您的表行的宽度比SELECT列表中的三列要宽,如果您从其中仅进行索引扫描,则部分 covering 索引可能会有所帮助。同样,需要满足一些前提条件。而且每个索引还具有存储和维护成本。

此外:评论声称,无法索引NULL值。这是不正确的,可以为NULL值建立索引。效率不及其他值,但差异不大。同样与当前案件无关。

答案 2 :(得分:0)

我认为您可以对此使用索引。像这样:

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;

这应该在("CITY", "AREA", "REGION")上使用SELECT DISTINCT上的索引-这对于该查询来说可能是昂贵的操作。

也就是说,查询将返回很多数据。因此,即使使用该索引也可能不会显着改善整体性能。