PostgreSQL码农集散地

AI辅助 PolarDB内核学习 - 26 优化器(plan模块) 核心模块 initsplan.c

AI辅助 PolarDB内核学习 - 26 优化器(plan模块) 核心模块 initsplan.c

代码作用简述:
initsplan.c 是 PostgreSQL 优化器的核心模块,负责初始化查询的基表信息、分解 WHERE/JOIN 条件到对应关系、构建等价类、处理 LATERAL 引用及外键约束,为后续的路径优化奠定基础。

内核开发者视角 - 核心机制解析

Image


关键代码逻辑:

  1. 条件分发 (distribute_qual_to_rels)

  • 检查外连接延迟 (check_outerjoin_delay)
  • 识别可合并条件 (check_mergejoinable)
  • 分发到单表或连接关系 (distribute_restrictinfo_to_rels)
  • 输入:原始条件(如 A.id=B.aid)
  • 处理:
  • 输出:RestrictInfo 结构,标记作用域和属性
  • 等价类生成 (generate_base_implied_equalities)

    // 示例:WHERE A.x=B.y AND B.y=10
    if (ec->ec_has_const) {
        generate A.x=10// 生成跨表等价
    }
  • 架构师视角 - 模块设计

    Image


    设计亮点:

    • 动态条件延迟:通过 check_outerjoin_delay 处理外连接语义约束,确保条件在正确层级应用
    • 外键智能匹配:match_foreign_keys_to_quals 将外键约束与查询条件关联,提升多表连接估算精度
    • LATERAL依赖追踪:find_lateral_references 确保横向引用变量正确传递

    应用开发者视角 - 查询优化示例

    场景:多表 JOIN 性能优化

    EXPLAINSELECT * 
    FROM orders o JOIN customers c ON o.cid = c.id
    WHERE o.total > 100AND c.country = 'US';

    优化器行为:

    1. 将 o.total > 100 下推至 orders 表 (distribute_restrictinfo_to_rels)
    2. 识别 o.cid=c.id 为等值连接,生成等价类
    3. 若存在 (customers.id) REFERENCES orders(cid) 外键,使用 FK 基数估算

    DBA视角 - 调优实践

    关键参数与诊断:

    -- 查看条件分布
    EXPLAIN (VERBOSE) SELECT ...;

    -- 检查外键利用
    SELECT * FROM pg_stats WHERE tablename = 'orders';

    -- 控制连接重排序
    SET join_collapse_limit = 8; 

    常见问题与对策:

    现象
    根因
    解决方案
    顺序扫描低效
    条件未下推
    检查 WHERE 条件索引
    嵌套循环耗时
    缺少等价类
    添加组合索引或调整连接顺序
    外连接性能差
    可空列估算偏差
    手动更新统计或使用 LEAKPROOF 函数

    核心创新 - 条件延迟处理

    机制:

    staticboolcheck_outerjoin_delay(...){
    do {
    // 遍历所有下层外连接
    if (当前条件依赖外连接可空侧) {
                relids = 合并外连接两侧 rels;  // 强制提升作用域
                delayed = true;
            }
        } while (发现新的依赖);
    }

    效果:避免过早过滤外连接产生的 NULL 行,确保查询语义正确性。例如:

    SELECT * FROM A LEFTJOIN B ON A.id=B.aid WHERE B.x > 10;
    -- 若 B 未匹配,B.x 为 NULL,WHERE 条件需在 JOIN 后应用

    总结:
    initsplan.c 通过精细的条件分发和语义分析,构建查询优化的核心框架。开发者需关注等价类与统计信息的交互,DBA 应结合执行计划分析索引与参数调优,而架构师则需理解模块间的数据流以设计高效查询引擎。