Nur*_*bek 6 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
Run Code Online (Sandbox Code Playgroud)
youtube我在 sql 语句中使用的表有 2500 万条记录。我认为这就是为什么查询需要 15-17 秒才能完成。对于我使用该查询的 Web 项目,它太长了。我正在尝试加快请求。
我为 youtube 表创建了这样的索引:
CREATE INDEX youtube_location_idx ON public.youtube USING btree ("CITY", "AREA", "REGION");
Run Code Online (Sandbox Code Playgroud)
在这一步之后,我再次运行查询,但需要相同的时间才能完成。似乎查询不使用索引。我如何知道查询中是否使用了任何索引?
Erw*_*ter 11
您自己通过运行回答了标题中的问题EXPLAIN。查询计划显示使用了哪些索引以及如何使用。有关详细信息,请参阅手册中的“使用 EXPLAIN”一章。
至于为什么查询使用顺序扫描而没有索引:2500万行,2992781 rows removed. 您正在获取24709900 rows,这几乎是所有行。
这永远不会很快。
这永远不会使用索引。
使用索引仅对所有行的一小部分有意义。否则只会增加额外的成本。根据许多共同因素,Postgres 查询规划器开始考虑所有行的大约 5% 或更少的 btree 索引。有关的:
好吧,如果您的表格行比SELECT列表中的三列宽得多,那么如果您从中获得仅索引扫描,部分覆盖索引可能会有所帮助。同样,需要满足一些先决条件。而且每个索引也有存储和维护成本。
旁白:一条评论声称,无法为 NULL 值编制索引。这是不正确的,NULL 值可以被索引。不如其他值那么有效,但没有太大区别。也与手头的案件无关。
我知道 PostgreSQL 中有四种类型的扫描。
顺序扫描:不使用索引。
索引扫描:先搜索索引,再搜索表。
仅索引扫描:仅搜索索引,不扫描实际表。
位图堆扫描:介于索引扫描和顺序扫描之间。
结果的第三行(seq scan)显示它按顺序扫描整个表。所以你没有使用索引。