You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL多表联合视图的查询计划器非最优执行计划问题

PostgreSQL多租户工作区Schema视图性能优化问题

数据库结构说明

我们的PostgreSQL数据库按租户和工作区划分多个Schema,结构如下:

reports/tenant1/workspace1
reports/tenant1/workspace2
reports/tenant2/workspace1
reports/tenant3/workspace1
reports/tenant3/workspace2
reports/tenant3/workspace3

每个工作区Schema包含结构完全一致的表集合,且每张表都包含_tenant和_workspace列,值与所在Schema的租户、工作区一一对应(例如reports/tenant1/workspace1下的表,这两列值为tenant1和workspace1)。

视图定义方式

在public Schema中,我们为每个表创建了对应的视图,用于联合所有工作区Schema中同结构的表。以example_table对应的example_view为例,视图定义如下:

SELECT _tenant, _workspace, column1, column2, column3
FROM "reports/tenant1/workspace1".example_table
WHERE _tenant = 'tenant1' AND _workspace = 'workspace1'
UNION ALL
SELECT _tenant, _workspace, column1, column2, column3
FROM "reports/tenant1/workspace2".example_table
WHERE _tenant = 'tenant1' AND _workspace = 'workspace2'
UNION ALL
SELECT _tenant, _workspace, column1, column2, column3
FROM "reports/tenant2/workspace1".example_table
WHERE _tenant = 'tenant2' AND _workspace = 'workspace1'
UNION ALL
-- 后续其他工作区的SELECT语句

注:每个SELECT语句中添加了“冗余”的分区谓词,目的是提示PostgreSQL在查询视图时跳过无关分区表。EXPLAIN ANALYZE显示这些无关表的查询确实“(never executed)”,但这一点似乎没被查询计划器在规划阶段利用。

性能问题表现

查询由BI工具发起,工具会根据登录用户属性自动为_tenant和_workspace列添加过滤谓词。当工作区数量达到50+后,查询视图的执行计划远不如直接查询底层表高效:

查询视图的慢查询(耗时约1分钟,使用嵌套循环连接)

SELECT * FROM
(
  SELECT column1, column2, column3
  FROM example_view1
  WHERE _tenant = 'tenant1' AND _workspace = 'workspace1'
) v1
JOIN
(
  SELECT column4, column5, column6
  FROM example_view2
  WHERE _tenant = 'tenant1' AND _workspace = 'workspace1'
) v2
ON v1.column1 = v2.column4

直接查询底层表的快查询(耗时不到1秒,使用哈希连接)

SELECT * FROM
(
  SELECT column1, column2, column3
  FROM "reports/tenant1/workspace1".example_table1
  WHERE _tenant = 'tenant1' AND _workspace = 'workspace1'
) v1
JOIN
(
  SELECT column4, column5, column6
  FROM "reports/tenant1/workspace1".example_table2
  WHERE _tenant = 'tenant1' AND _workspace = 'workspace1'
) v2
ON v1.column1 = v2.column4

注:子查询是BI工具查询生成器的默认生成方式,无实际业务意义。

核心疑问

如何让查询计划器在规划阶段就知晓:除了匹配_tenant和_workspace谓词的分区表外,其他所有表都不会返回结果,可以直接忽略?目前只有执行阶段才会跳过无关表,但规划阶段仍会考虑所有表,导致执行计划低效。


内容的提问来源于stack exchange,提问作者eskrm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 10:40:41