我有点困惑,需要一些建议。我使用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
3条答案
按热度按时间drnojrws1#
您通过运行
EXPLAIN
自己回答了标题中的问题。查询计划显示了使用哪些索引以及如何使用。有关详细信息,请参阅手册中的"UsingEXPLAIN
"一章。至于为什么查询使用顺序扫描而没有索引:2500万行,
992781 rows removed
。你正在获取24709900 rows
,这几乎是所有的行。这永远不会很快,它只会在特殊情况下使用索引。
使用索引通常只对所有行的一小部分有意义。否则它只会增加额外的成本。根据一些辅助因素,Postgres查询规划器开始考虑对所有行的5%或更少的btree索引。相关信息:
好吧,如果你的表行比
SELECT
列表中的三列宽得多,如果你只扫描索引,一个(部分)* 覆盖 * 索引可能会有所帮助。同样,需要满足一些先决条件。每个索引也会增加存储和维护成本。旁白:一条评论声称
NULL
值无法被索引。这是不正确的,NULL
值可以被索引。不像其他值那样有效,但没有太大的区别。也与手头的案例无关。7vux5j2d2#
我知道PostgreSQL中有四种类型的扫描。
**顺序扫描:**不使用索引。
**索引扫描:**先扫描索引,再扫描表。
**只扫描索引:**只扫描索引,不扫描实际表。
**位图堆扫描:**介于索引扫描和顺序扫描之间。
结果的第三行(seq scan)显示它按顺序扫描整个表。所以你没有使用索引。
xkftehaa3#
我认为你可以用一个索引来描述它。比如:
字符串
这应该对
SELECT DISTINCT
使用("CITY", "AREA", "REGION")
上的索引--对于这个查询来说,这可能是一个开销很大的操作。也就是说,查询将返回大量数据,因此即使使用索引也可能不会显著提高整体性能。