我试图让Postgis只使用索引扫描,但它执行位图索引扫描到位图堆扫描.

我得到了下表——包含5万行:

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;

Postgis告诉我,INCLUDE语句不能使用合适的覆盖索引,这是不受支持的.

Performed request:

SELECT geometry, code_iris
  FROM forme_iris iris
  WHERE ST_Intersects(iris.geometry, ST_SetSrid(ST_GeomFromGeoJson('<geojson>'), 4326))

它返回821行,在执行请求之前,我已经清空并分析了表.

PostgreSQL version:x86_64-pc-linux-gnu上的PostgreSQL 11.12,由gcc(gcc)7.3.1 20180712(Red Hat 7.3.1-12)编译,64位

Postgis version:2.5使用_GEOS=1使用_PROJ=1使用_STATS=1

101 output: https://explain.dalibo.com/plan/TJQt

谢谢

推荐答案

PostGIS GiST索引压缩值(它们存储一个边界框),并且没有"获取"方法,因此它们无法进行仅索引扫描:

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)

the documentation:

GiST的索引运算符类必须提供五种方法,六种是可选的.[...]

compress

将数据项转换为适合索引页中物理存储的格式.如果省略了compress方法,则数据项将存储在索引中而不进行修改.

fetch

将数据项的压缩索引表示形式转换为原始数据类型(仅用于索引扫描).返回的数据必须是原始索引值的准确无损副本.

文档中没有包含这些方法的编号,您必须咨询来源.

Postgresql相关问答推荐

利用PostgreSQL查询中表的顺序来计算包含每次时间的时间范围

为MCV扩展统计设置统计目标

PostgreSQL bytea 网络流量双倍预期值

Windows上的psql:错误:编码UTF8的字节序列无效:0xc8 0x20

Postgres内部如何计算月份间隔

PostgreSQL unnest 与空数组

OpenShift:如何从我的 PC 连接到 postgresql

表或列名不能以数字开头?

INSERT RETURNING 是否保证以 right的顺序返回?

为什么 SQLAlchemy 不创建串行列?

SQL数据库表中的多态性?

如何将两个 PostgreSQL 列聚合到一个用括号分隔的数组

Postgres - 如果找不到记录,则在更新时返回错误

为 postgresql 存储过程设置隔离级别

如何从 PostgreSQL 中的 Json 数组中获取元素

使用 Postgres 在 Rust 的 Diesel 库中添加时间戳

Postgresql滚动删除旧行?

在 Select (PostgreSQL/pgAdmin) 中将布尔值返回为 TRUE 或 FALSE

JOIN (SELECT ... ) ue ON 1=1?

PostgreSQL 中 from dual 的等价性