Postgis 不只使用索引扫描
Postgis not using index scan only
我试图让 Postgis 仅使用索引扫描,但它正在将位图索引扫描执行到位图堆扫描中。
我得到以下 table - 包含 50k 行:
CREATE TABLE IF NOT EXISTS public.forme_iris
(
code_iris character varying(20) COLLATE pg_catalog."default" NOT NULL,
geometry geometry,
CONSTRAINT forme_iris_pkey PRIMARY KEY (code_iris)
)
我创建了这个索引:
CREATE INDEX forme_iris_geometry_idx1
ON public.forme_iris USING gist
(geometry, code_iris)
TABLESPACE pg_default;
我无法在 INCLUDE
语句中使用适当的覆盖索引,Postgis 告诉我这不受支持。
执行请求:
SELECT geometry, code_iris
FROM forme_iris iris
WHERE ST_Intersects(iris.geometry, ST_SetSrid(ST_GeomFromGeoJson('<geojson>'), 4326))
它 returns 821 行,在执行请求之前我已经清理并分析了 table。
PostgreSQL 版本:x86_64-pc-linux-gnu 上的 PostgreSQL 11.12,由 gcc (GCC) 7.3.1 20180712 (Red Hat 7.3.1-12) 编译,64 位
Postgis 版本: 2.5 USE_GEOS=1 USE_PROJ=1 USE_STATS=1
EXPLAIN ANALYZE
输出: https://explain.dalibo.com/plan/TJQt
谢谢!
我也无法让它完成 IOS,即使使用 INCLUDE(它在 v12 中被 GiST 支持)也不行。
然而,在我看来,CPU 一直在检查你的几何列与你的怪物 geojson,我认为即使你能够获得 index-only扫描。因此,即使您可以让它使用 index-only 扫描,它实际上也可能无济于事。
PostGIS GiST 索引压缩值(它们存储边界框)并且没有“获取”方法,因此它们无法进行 index-only 扫描:
SELECT opf.opfname,
amp.amprocnum,
amp.amproc::regproc
FROM pg_opfamily AS opf
JOIN pg_amproc AS amp ON opf.oid = amp.amprocfamily
JOIN pg_am ON opf.opfmethod = pg_am.oid
WHERE pg_am.amname = 'gist'
AND amp.amprocnum IN (3, 9) -- 3 is "compress", 9 is "fetch"
AND opf.opfname LIKE '%geometry%';
opfname │ amprocnum │ amproc
══════════════════════╪═══════════╪═══════════════════════════
gist_geometry_ops_2d │ 3 │ geometry_gist_compress_2d
gist_geometry_ops_nd │ 3 │ geometry_gist_compress_nd
(2 rows)
There are five methods that an index operator class for GiST must provide, and six that are optional. [...]
compress
Converts a data item into a format suitable for physical storage in an index page. If the compress
method is omitted, data items are stored in the index without modification.
[...]
fetch
Converts the compressed index representation of a data item into the original data type, for index-only scans. The returned data must be an exact, non-lossy copy of the originally indexed value.
文档没有涵盖这些方法的编号,您必须查阅来源。
我试图让 Postgis 仅使用索引扫描,但它正在将位图索引扫描执行到位图堆扫描中。
我得到以下 table - 包含 50k 行:
CREATE TABLE IF NOT EXISTS public.forme_iris
(
code_iris character varying(20) COLLATE pg_catalog."default" NOT NULL,
geometry geometry,
CONSTRAINT forme_iris_pkey PRIMARY KEY (code_iris)
)
我创建了这个索引:
CREATE INDEX forme_iris_geometry_idx1
ON public.forme_iris USING gist
(geometry, code_iris)
TABLESPACE pg_default;
我无法在 INCLUDE
语句中使用适当的覆盖索引,Postgis 告诉我这不受支持。
执行请求:
SELECT geometry, code_iris
FROM forme_iris iris
WHERE ST_Intersects(iris.geometry, ST_SetSrid(ST_GeomFromGeoJson('<geojson>'), 4326))
它 returns 821 行,在执行请求之前我已经清理并分析了 table。
PostgreSQL 版本:x86_64-pc-linux-gnu 上的 PostgreSQL 11.12,由 gcc (GCC) 7.3.1 20180712 (Red Hat 7.3.1-12) 编译,64 位
Postgis 版本: 2.5 USE_GEOS=1 USE_PROJ=1 USE_STATS=1
EXPLAIN ANALYZE
输出: https://explain.dalibo.com/plan/TJQt
谢谢!
我也无法让它完成 IOS,即使使用 INCLUDE(它在 v12 中被 GiST 支持)也不行。
然而,在我看来,CPU 一直在检查你的几何列与你的怪物 geojson,我认为即使你能够获得 index-only扫描。因此,即使您可以让它使用 index-only 扫描,它实际上也可能无济于事。
PostGIS GiST 索引压缩值(它们存储边界框)并且没有“获取”方法,因此它们无法进行 index-only 扫描:
SELECT opf.opfname,
amp.amprocnum,
amp.amproc::regproc
FROM pg_opfamily AS opf
JOIN pg_amproc AS amp ON opf.oid = amp.amprocfamily
JOIN pg_am ON opf.opfmethod = pg_am.oid
WHERE pg_am.amname = 'gist'
AND amp.amprocnum IN (3, 9) -- 3 is "compress", 9 is "fetch"
AND opf.opfname LIKE '%geometry%';
opfname │ amprocnum │ amproc
══════════════════════╪═══════════╪═══════════════════════════
gist_geometry_ops_2d │ 3 │ geometry_gist_compress_2d
gist_geometry_ops_nd │ 3 │ geometry_gist_compress_nd
(2 rows)
There are five methods that an index operator class for GiST must provide, and six that are optional. [...]
compress
Converts a data item into a format suitable for physical storage in an index page. If the
compress
method is omitted, data items are stored in the index without modification. [...]
fetch
Converts the compressed index representation of a data item into the original data type, for index-only scans. The returned data must be an exact, non-lossy copy of the originally indexed value.
文档没有涵盖这些方法的编号,您必须查阅来源。