尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
pgrust 优化器原理:基于代价的查询优化在 Rust 中的移植
pgrust 优化器原理基于代价的查询优化在 Rust 中的移植【免费下载链接】pgrustPostgres rewritten in Rust, now faster than Postgres and Clickhouse项目地址: https://gitcode.com/GitHub_Trending/pg/pgrustpgrust 优化器是用 Rust 重写 Postgres这一宏大工程中最硬核的部分它把 PostgreSQL 18.3 那套经过二十多年打磨的**基于代价的查询优化Cost-Based Optimization**逻辑一行行安全地移植到了 Rust。pgrust 目前已经能对齐超过 46,000 条 Postgres 回归测试查询而优化器正是保证输出和 Postgres 一模一样的关键枢纽。这篇文章会从零讲清楚什么是基于代价的优化、pgrust 优化器的代码长什么样、以及 Rust 移植背后的巧妙设计。什么是基于代价的查询优化新手可能好奇SQL 只是一句话为什么执行前要优化因为同一句 SQL 有无数种执行方式。例如SELECT * FROM a JOIN b ON a.idb.id可以嵌套循环连接Nest Loop外层逐行驱动内层可以哈希连接Hash Join把一边建哈希表再探测可以归并连接Merge Join两边先排序再合并还可以先做索引扫描、位图扫描、并行扫描……哪种最快取决于表有多少行、数据分布、有没有索引、内存多大。Postgres 的思路是给每种方案算一个代价分数选分数最低的。这个算分的过程就是基于代价的查询优化。而pgrust 优化器要做的就是把 Postgres 里负责算分与选路的整条流水线在 Rust 里原样复刻。pgrust 优化器代码地图 ️pgrust 的优化器完整落在crates/backend/optimizer/目录下结构与 Postgres 源码一一对应模块对应 Postgres 文件职责path/costsize/costsize.c代价模型与估算最核心path/allpaths/allpaths.c顶层路径搜索驱动path/indxpath/indxpath.c索引路径生成path/joinpath/joinrels/joinpath.c、joinrels.c连接路径与连接顺序搜索path/equivclass/、pathkeys/equivclass.c、pathkeys.c等价类与排序键推导plan/createplan/createplan.c把最优路径翻译成执行计划两个必看入口costsize 代价模型主文件整个优化器的心脏createplan 路径转计划路径到计划的分发器。代价模型核心startup_cost 与 total_cost Postgres 的代价计算用一对数字描述每个路径startup_cost启动代价输出第一行前要花的代价比如排序要先排完才能输出total_cost总代价输出完所有行总共要花的代价。估算时按扫描页数 × 页代价 处理行数 × CPU 代价累加。pgrust 在costsize/src/lib.rs中原样保留了 Postgres 的默认常量代价常量默认值含义seq_page_cost1.0顺序读一页的代价random_page_cost4.0随机读一页的代价磁盘寻道贵cpu_tuple_cost0.01处理一行元组的 CPU 代价cpu_index_tuple_cost0.005处理一行索引元组的代价cpu_operator_cost0.0025执行一次操作符的代价parallel_tuple_cost0.1并行传输一行数据的代价这些常量在 Rust 里用thread_local的Cell保存既保证了并发安全又允许运行时通过 GUC 修改——和 C 全局变量语义一致。代码里可以看到非常忠实的一对一移植pub const DEFAULT_SEQ_PAGE_COST: f64 1.0; pub const DEFAULT_RANDOM_PAGE_COST: f64 4.0;估算环节选择性Selectivity与基数估算 代价再准前提是基数估算准这条 SQL 到底会过滤出多少行pgrust 的costsize/src/sizeest.rs移植了set_baserel_size_estimates等函数用表的总行数乘以限制条件的选择性selectivity0~1 之间得到估算行数再套上clamp_row_est防止估算值越界。比如 VALUES 子句的行数直接等于列表长度函数扫描的行数取所有函数返回行数的最大值——细节都和 Postgres 完全一致。路径生成连接搜索的两种策略 当一条查询涉及多张表时连接顺序的选择是指数级的。pgrust 的path/allpaths/src/joinsearch.rs移植了make_rel_from_joinlist和standard_join_search表数量少时用动态规划逐层枚举连接组合选出全局最优表数量超过geqo_threshold默认 12时切换GEQO遗传算法近似搜索避免组合爆炸。有趣的是 pgrust 连 GEQO 也移植了相关代码在 geqo_all 中。它甚至把插件 hook 为空、核心搜索默认路径这种 Postgres 的运行时分支行为都保留了下来。每一步都能被开关控制enable_* 系列 GUC ️Postgres 允许 DBA 用SET enable_seqscanoff这类开关禁用某种执行方式。pgrust 也移植了整套机制见 costsize 的 GUC 模块扫描类enable_seqscan、enable_indexscan、enable_indexonlyscan、enable_bitmapscan连接类enable_nestloop、enable_mergejoin、enable_hashjoin聚合与并行类enable_hashagg、enable_parallel_hash、enable_partitionwise_join等每个开关都是一个thread_local布尔 Cell通过 GUC 表的访问器读写保证SET enable_hashjoinoff之后代价计算真的会把哈希连接路径罚到禁用。从最优路径到执行计划最后一公里 代价最低的路径选出来后还要把它翻译成真正的执行计划树。这一步由 createplan 模块 完成它按路径类型分发create_plan_recurse把 36 种PathNode变体逐一转换为对应的 Plan 节点——序列扫描、索引扫描、嵌套循环、聚合……一应俱全。注释里写得很清楚这是对createplan.c的1:1 移植。Rust 移植的三大工程巧思 ️1. Arena 模型没有生命周期的 PlannerInfoPostgres 里PlannerInfo是一棵充满指针的树。Rust 里指针要管生命周期pgrust 的做法是把Path、Node等都放进arena区域分配器用PathId、RelId、NodeId这类句柄代替裸指针。这样PlannerInfo本身不携带生命周期既安全又高效。2. Seam 机制让没移植完的代码也能编译整个 pgrust 是逐步移植的模块间互相依赖。它发明了seam接缝机制跨模块调用先声明一个接缝实现方没落地时先panic 占位落地后再接入。这让优化器在依赖未完成时也能整体编译、逐块点亮——注释里称之为 mirror PG and panic。3. 无 unsafe 代码allpaths模块第一行就是#![forbid(unsafe_code)]。整个优化器在Safe Rust下运行内存安全由编译器保证这是相对 C 实现最大的工程红利。为什么优化器移植值得关注pgrust 的目标不只是能用 Rust 跑 Postgres而是从内部让 Postgres 更容易被改造保持 Postgres 的行为形状、把官方回归测试当作裁判再借助 Rust 的安全性和 AI 辅助编程探索更深层的服务端改动。Roadmap 里那些大胆设想——线程化内核、内置连接池、杜绝突然变差的执行计划——全都建立在优化器这套确定性的地基之上。理解 pgrust 优化器你就理解了 Postgres 查询优化的全貌也看到了一个 C 大型系统被系统性重写为 Rust 的绝佳范本。如果你也想动手研究从costsize的代价常量开始读起是最友好的切入点。【免费下载链接】pgrustPostgres rewritten in Rust, now faster than Postgres and Clickhouse项目地址: https://gitcode.com/GitHub_Trending/pg/pgrust创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

github-for-jira 之 Smart Commits 终极指南:在提交信息中自动更新 Jira 工单状态

github-for-jira 之 Smart Commits 终极指南:在提交信息中自动更新 Jira 工单状态

github-for-jira 之 Smart Commits 终极指南:在提交信息中自动更新 Jira 工单状态 【免费下载链接】github-for-jira DEPRECATED (moved to private repository) - Connect your code with your project management in Jira 项目地址: https://gitcode.com/gh_mir…

📅 2026/10/23 6:40:15
一文读懂AsmSpy:.NET程序集引用检查神器完全指南

一文读懂AsmSpy:.NET程序集引用检查神器完全指南

一文读懂AsmSpy:.NET程序集引用检查神器完全指南 【免费下载链接】AsmSpy Simple command line assembly reference checker 项目地址: https://gitcode.com/gh_mirrors/as/AsmSpy .NET 开发中,程序集引用检查是最容易让人头疼的问题之一&#xf…

📅 2026/10/5 20:58:50
SaveGameFree 自动存档组件 SaveGameAuto 详解:零代码保存游戏进度

SaveGameFree 自动存档组件 SaveGameAuto 详解:零代码保存游戏进度

SaveGameFree 自动存档组件 SaveGameAuto 详解:零代码保存游戏进度 【免费下载链接】SaveGameFree Save Game Free is a free and simple but powerful solution for saving and loading game data in unity. 项目地址: https://gitcode.com/gh_mirrors/sa/SaveGa…

📅 2026/9/21 2:28:43
MORE NEWS

更多资讯

📰

第三章:9、工作流编排进阶

概览:支持灵活的条件分支与并行处理可复用子工作流实现流程嵌套通过 Webhook、消息队列等方式与外部系统无缝集成一、条件分支与并行网关1. 条件分支根据工单严重程度,自动路由到不同的处理流程:Configuration public class TicketWorkflowCo…

📰

程序员转型AI,涨薪40%的真相:别裸辞,看懂公司预算流向!

文章讲述了Java后端工程师转型AI后的薪资增长,指出淘汰程序员的不是新技术,而是公司预算流向。大模型岗位需求激增,薪资普遍高于传统岗位,但公司更需要的是懂AI的应用架构师而非简单的CRUD开发者。老工程师的经验在AI转型中成为优…

📰

7个模型外部工程实践,让你的AI Agent从“会聊天”变“能干活”!

本文深入探讨了构建高效AI Agent的关键要素,即模型之外的工程实践。从提示词工程、上下文工程、RAG检索增强生成,到工具调用、Agent记忆、子智能体编排,最后是评测体系,这七大组件共同构成了Agent能力的骨架。文章强调&#xff0c…

📰

Java开发者必看:掌握AI应用开发,收藏这份高薪转型指南!

文章指出,AI相关岗位需求激增,传统Java后端岗位面临收缩,但"JavaAI"复合型人才薪资溢价高达50%。文章分析了JavaAI岗位的核心能力要求,包括LLM接入、Agent工程化和AI驱动的性能优化,并提供了转型路径建议&am…

📰

小白程序员必看:收藏这份 LangChain RAG 实战指南

本文基于 LangChain 官方文档,深入解析 RAG 技术在大模型中的应用。从 RAG 的核心原理到 Deep Agents 的四种实现模式,详细阐述了如何为 LLM 提供外部知识访问能力,并重点解析了“检索-卸载-委托”模式。文章还涵盖了索引阶段、检索-生成阶段…

📰

智学文枢:学生与习题的状态中枢

student_store / question_store:学生与习题的状态中枢一句话摘要:学生是档案主体、习题是分析对象,StudentStore 与 QuestionStore 各自管好"内存缓存 CRUD Signal 广播",一个专注档案与分科配置,一个连图…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬