PostgreSQL关联视图查询为何扫描外键表?执行计划疑问求解
PostgreSQL 关联视图查询的执行计划疑问及优化需求
问题背景
基于PostgreSQL 16.9,存在对关联视图查询逻辑的疑惑:当查询仅涉及单表主键的字段时,执行计划却扫描了关联的外键表,怀疑对主键、外键及参照完整性的理解与PostgreSQL实际处理逻辑存在偏差。
表结构定义
tbla表结构:
testv=> \d tbla Table "public.tbla" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+----------------------------------- apk | bigint | | not null | nextval('tbla_apk_seq'::regclass) aval | integer | | not null | Indexes: "tbla_pkey" PRIMARY KEY, btree (apk) Referenced by: TABLE "tblb" CONSTRAINT "tblb_ak_fkey" FOREIGN KEY (ak) REFERENCES tbla(apk) ON DELETE CASCADE
tblb表结构:
testv=> \d tblb Table "public.tblb" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+----------------------------------- bpk | bigint | | not null | nextval('tblb_bpk_seq'::regclass) ak | bigint | | not null | bval | integer | | not null | Indexes: "tblb_pkey" PRIMARY KEY, btree (bpk) Foreign-key constraints: "tblb_ak_fkey" FOREIGN KEY (ak) REFERENCES tbla(apk) ON DELETE CASCADE
关联视图定义
joinv视图结构及定义:
testv=> \d+ joinv View "public.joinv" Column | Type | Collation | Nullable | Default | Storage | Description --------+---------+-----------+----------+---------+---------+------------- ak | bigint | | | | plain | bk | bigint | | | | plain | aval | integer | | | | plain | bval | integer | | | | plain | View definition: SELECT a.apk AS ak, b.bpk AS bk, a.aval, b.bval FROM tbla a JOIN tblb b ON a.apk = b.ak;
核心疑惑点
- 查询
joinv中的ak字段(对应tbla的主键apk)时,因tblb.ak是NOT NULL外键,参照完整性已保证其所有值均存在于tbla中,按逻辑只需扫描tbla即可,但执行计划却显示扫描了tblb。 - 排序方式改为ASC时,执行计划差异显著;DESC排序时,执行计划中的
Rows Removed by Join Filter: 173463数值来源不明,与现有统计数据不符。 select count(ak) from joinv和select count(distinct ak) from joinv的执行逻辑存在明显差异。- 多表INNER JOIN的执行计划和性能存在无规律波动。
需求
希望获取比PostgreSQL官方手册更通俗易懂的JOIN构建原理与性能优化实操资料。
内容的提问来源于stack exchange,提问作者John Daschbach
相关产品推荐
相关产品推荐

