我如何知道查询中是否使用了任何索引 | PostgreSQL 11?
How do I know if any index is used in a query | PostgreSQL 11?
我有点困惑,需要一些建议。我使用 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
table 有 2500 万条记录。我认为这就是为什么查询需要 15-17 秒才能完成的原因。对于我使用该查询的 Web 项目,它太长了。我正在尝试加快请求速度。
我为 youtube 创建了这样的索引 table:
CREATE INDEX youtube_location_idx ON public.youtube USING btree ("CITY", "AREA", "REGION");
完成此步骤后,我 运行 再次查询,但需要相同的时间才能完成。查询似乎不使用索引。我如何知道查询中是否使用了任何索引?
解释分析 return:
您在手册中 运行 EXPLAIN
. The query plan shows which indexes are used and how. For details see the chapter "Using EXPLAIN
" 自己回答了标题中的问题。
至于为什么查询使用顺序扫描且没有索引:2500万行,992781 rows removed
。您正在获取 24709900 rows
,这几乎是所有行。
这永远不会很快。
这只会在特殊情况下使用索引。
使用索引通常只对所有行的一小部分有意义。否则只会增加额外的成本。根据 co-factors 的数量,Postgres 查询规划器开始考虑为所有行的大约 5% 或更少使用 btree 索引。相关:
好吧,如果您的 table 行比 SELECT
列表中的三列宽很多,(部分)covering 索引可能会有所帮助如果你得到 index-only 扫描出来。同样,需要满足一些先决条件。而且每个索引还增加了存储和维护成本。
旁白:一条评论声称 NULL
值无法编入索引。这是不正确的,NULL
个值可以被索引。不如其他值有效,但没有太大区别。也与本案无关。
我想你可以在这上面使用索引。类似于:
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")
上的索引 -- 这可能是该查询的昂贵操作。
也就是说,查询将要 return 大量数据。所以即使使用索引也可能不会对整体性能有明显的改善。
我知道在 PostgreSQL 中有四种扫描类型。
顺序扫描:不使用索引。
索引扫描: 搜索索引,然后 table。
仅索引扫描: 仅搜索索引,不扫描实际 table。
位图堆扫描:介于索引扫描和顺序扫描之间。
结果的第三行(seq 扫描)表明它按顺序扫描整个 table。所以你没有使用索引。
我有点困惑,需要一些建议。我使用 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
table 有 2500 万条记录。我认为这就是为什么查询需要 15-17 秒才能完成的原因。对于我使用该查询的 Web 项目,它太长了。我正在尝试加快请求速度。
我为 youtube 创建了这样的索引 table:
CREATE INDEX youtube_location_idx ON public.youtube USING btree ("CITY", "AREA", "REGION");
完成此步骤后,我 运行 再次查询,但需要相同的时间才能完成。查询似乎不使用索引。我如何知道查询中是否使用了任何索引?
解释分析 return:
您在手册中 运行 EXPLAIN
. The query plan shows which indexes are used and how. For details see the chapter "Using EXPLAIN
" 自己回答了标题中的问题。
至于为什么查询使用顺序扫描且没有索引:2500万行,992781 rows removed
。您正在获取 24709900 rows
,这几乎是所有行。
这永远不会很快。
这只会在特殊情况下使用索引。
使用索引通常只对所有行的一小部分有意义。否则只会增加额外的成本。根据 co-factors 的数量,Postgres 查询规划器开始考虑为所有行的大约 5% 或更少使用 btree 索引。相关:
好吧,如果您的 table 行比 SELECT
列表中的三列宽很多,(部分)covering 索引可能会有所帮助如果你得到 index-only 扫描出来。同样,需要满足一些先决条件。而且每个索引还增加了存储和维护成本。
旁白:一条评论声称 NULL
值无法编入索引。这是不正确的,NULL
个值可以被索引。不如其他值有效,但没有太大区别。也与本案无关。
我想你可以在这上面使用索引。类似于:
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")
上的索引 -- 这可能是该查询的昂贵操作。
也就是说,查询将要 return 大量数据。所以即使使用索引也可能不会对整体性能有明显的改善。
我知道在 PostgreSQL 中有四种扫描类型。
顺序扫描:不使用索引。
索引扫描: 搜索索引,然后 table。
仅索引扫描: 仅搜索索引,不扫描实际 table。
位图堆扫描:介于索引扫描和顺序扫描之间。
结果的第三行(seq 扫描)表明它按顺序扫描整个 table。所以你没有使用索引。