Query Optimizer

10 篇内容

技术文章Phil Eaton - databases

Writing a SQL database from scratch in Go: 3. indexes

文章在 gosql 项目中扩展索引支持,涵盖 PRIMARY KEY 词法解析、红黑树索引创建、插入时索引维护和 SELECT 查询优化。作者使用 GoLLRB 红黑树存储索引项,通过识别 WHERE 条件中可应用索引的模式,先用索引预筛选行再执行过滤。文章分析当前查询计划仅支持 AND 连接和列与字面量比较,不能合并范围条件,且索引并非总是优于线性扫描。基准测试显示 100 万行插入时带索引内存和耗时增加,但等值查询从秒级降至微秒级,体现空间换时间的权衡。

推荐收录,因为文章通过写一个 Go 语言 SQL 数据库的索引模块,完整展示主键约束解析、红黑树索引构建、插入维护和查询预筛选的端到端实现,并给出有/无索引的实测性能对比。适合想理解数据库索引原理、查询规划和存储引擎实现的读者;其简化取舍与限制分析也可作为进一步阅读真实数据库文档与源码的入门桥梁。

工程实践SelectDB 技术分享

Apache Doris 倒排索引工作原理:全文检索提速 59 倍,点查提速 14 倍 我们基于开源分析型数据库 Apache Doris,针对包含 1.35 亿条数据的亚马逊评论数据集进行...

文章介绍 Apache Doris 内置倒排索引解决 OLAP 稀疏扫描问题的技术机制与实测效果。针对传统 OLAP 依赖列存、排序和 Zone Maps 在稀疏查询下全表扫描的局限,文章详细解析了三种索引结构:字符串精确匹配用 Posting List,数值范围过滤用 BKD 树,非结构化文本检索用分词器结合倒排列表。在 1.35 亿条亚马逊评论数据集上,50 并发测试显示全文检索提速 59 倍,按 ID 点查提速 156 倍,多维组合查询提速 10 倍。同时评估了资源开销:新增 7 个索引后存储从 26GB 增至 47GB,写入耗时增加约 6%,主要来自大文本列。结论认为 OLAP 内置倒排索引可简化 Elasticsearch+OLAP 双引擎架构,但应根据查询特征选择性建索引以控制成本。

推荐收录,因为文章基于 1.35 亿条真实数据给出可复现的建表、索引和查询测试,定量对比了性能提升与存储/写入开销。适合数据库内核开发者、 OLAP 架构师和数据平台团队参考,其倒排索引设计思路可迁移到类似分析型系统或评估 Elasticsearch 替代方案。需要注意的是测试仅基于单节点和特定数据集,索引列选择需按业务权衡。

工程实践Crunchy Data Blog

Hybrid Search Patterns with Postgres and pgvector

文章系统探讨了在PostgreSQL和pgvector中实现混合搜索(向量相似度加标量过滤)的工程模式。首先阐述了pgvector迭代索引扫描如何平衡召回与性能,然后分析了向量优先和标量优先两条路径各自的适用场景与局限。作者进一步提供了三种实用工作区:为低基数过滤构建部分HNSW索引;通过过采样再过滤应对高基数或临时过滤器;以及利用缓存加速重复查询。文中给出了过采样的估算公式、查询计划诊断方法以及各方案的决策指南,并强调了每种模式在召回率、性能和维护成本之间的权衡。

推荐收录,因为本文是针对Postgres+pgvector混合搜索问题的实战指南,从问题根源到四种解决方案给出了完整的权衡分析、代码示例和调优公式,远超简单教程。适合正在构建带标量过滤的向量搜索系统的工程师,文中部分索引、过采样和缓存等模式可直接应用于生产环境,决策树和EXPLAIN诊断方法具有跨场景的可迁移价值。

技术文章PlanetScale Blog

What's new in Postgres 19

文章详细介绍了 Postgres 19 的三个主要变化:在线表压缩 REPACK、默认禁用 JIT 以及查询规划器的多项改进。REPACK 功能将 VACUUM FULL 和 CLUSTER 整合为一个支持在线操作的命令,使用逻辑解码与复制槽实现非阻塞重写,但存在额外磁盘空间和 MVCC 安全等限制。默认禁用 JIT 是因为其对 OLTP 查询可能引入的编译开销,转而允许用户按需启用。查询规划器新增了早期聚合优化,可在特定条件下将聚合下推到连接之前,并改进了 NOT IN 的处理。文章通过示例和对比展示了这些特性的用法与边界,还简要提及了 lz4 默认 TOAST 压缩、并行 autovacuum 等其他改进,为 PostgreSQL 用户和管理员提供了全面的升级指导。

推荐收录,因文章不仅列出新特性,还深入解析了设计动机、内部机制(如 REPACK CONCURRENTLY 使用复制槽与快照实现在线重写)和实际影响(JIT 默认禁用的权衡),附带代码示例和注意事项。适合数据库管理员、后端开发者了解 PostgreSQL 19 的关键变化与适用场景,其技术深度和实用性对长期运维参考价值显著。

工程实践PlanetScale Blog

When the Postgres query planner goes rogue

文章记录了一次 PostgreSQL 生产事故:在没有代码或流量变化的情况下,数据库 CPU 飙升,查询延迟从毫秒级恶化到约 10 秒。通过监控工具定位到一个特定查询模式,发现其执行计划突然放弃索引而进行全表扫描。根因在于 PostgreSQL 查询优化器基于统计信息生成计划,而数据增长导致统计信息演变,使得优化器在罕见情况下选择次优计划。团队临时使用 Database Traffic Control 立即拦截该查询以恢复数据库健康,随后在安全环境通过 EXPLAIN 分析计划变化,并提出长期修复方案,包括执行 ANALYZE 刷新统计、调整索引或重写查询。文章展示了从发现现象、定位根因、应急止损到永久修复的完整工程流程,并点明查询计划不稳定的普遍风险与应对思路。

这篇文章是典型的数据库性能事件复盘,有明确的故障现象、诊断过程(延迟关联、计划变化对比)和分级应对方案。它不仅展示了应急响应手段,还解释了 PostgreSQL 优化器行为的技术背景,为 DBA 和开发者在类似场景下快速识别和修复计划退化提供了可迁移的经验。文中虽有产品功能描述,但技术分析独立且扎实,适合作为数据库稳定性实践案例收录。

技术文章Crunchy Data Blog

How to Read Postgres EXPLAIN: A Guide to Scan Types

这篇文章以 Postgres 的 EXPLAIN 输出为切入点,系统讲解了常见扫描类型及其适用场景,帮助读者从执行计划中判断查询为何快或慢。文章依次解释了顺序扫描、索引扫描、位图索引扫描与位图堆扫描、并行顺序扫描、并行索引扫描以及索引仅扫描,并配合真实的 EXPLAIN ANALYZE 示例展示各自的计划形态和指标。作者不仅说明了这些扫描方式的工作机制,还强调了优化器的选择逻辑,例如小表、返回比例较高或需要随机访问过多时,顺序扫描可能优于索引扫描。对于索引仅扫描,文章进一步讨论了覆盖索引带来的收益,以及写放大、索引体积和适用列数等边界条件。整体上,这是面向 PostgreSQL 性能排查与执行计划阅读的实用入门,但内容仍以常见扫描类型为主,未深入展开代价模型或更复杂的连接/排序计划。

文章直接给出了多种 EXPLAIN 扫描节点的真实输出和判读方法,适合做 PostgreSQL 性能排查、SQL 优化和执行计划入门参考。它的可迁移价值在于帮助读者建立“选择哪种扫描方式、为什么会选它”的心智模型,但内容主要覆盖基础扫描类型,深层优化仍需结合具体工作负载。

工程实践PlanetScale Blog

Optimizing aggregation in the Vitess query planner

这篇文章复盘了 Vitess 查询规划器中的一次聚合优化:一个包含 join、group by 和 order by 的查询因为无法把聚合下推到 MySQL,导致 VTGate 需要拉取大量数据并可能触发 OOM。作者先分析初始计划和树重写过程,说明 ordering under aggregation 过早执行时会把排序卡在 join 上游,从而阻断聚合下推。随后他利用规划器的阶段机制,延后该重写器直到 split aggregation 阶段,再让聚合穿过 join 下推到各个分片。最终 VTGate 只需合并各分片返回的部分聚合结果,而不是承担全量数据排序和聚合。文章的边界也很明确:该优化依赖重写阶段的时机控制,属于规划器内部顺序与算子可交换性之间的权衡。

文中给出了真实的 OOM 问题、初始执行树、重写前后计划和最终下推结果,是典型的数据库查询优化工程案例。适合做查询规划器、分布式 SQL 引擎和算子重写设计的参考,尤其对需要处理聚合下推与阶段控制的读者很有迁移价值。

技术文章PlanetScale Blog

Achieving data consistency with the consistent lookup Vindex

文章系统解释了 Vitess 的 Vindex 机制,重点聚焦于一致性查找 Vindex(consistent lookup vindex)如何在分片数据库中兼顾路由效率与数据一致性。作者先说明普通 lookup vindex 通过维护二级索引表,把查询从全分片扫描收敛到单分片命中;随后进一步指出,若主表与索引表分属不同分片,直接做跨分片事务会引入昂贵的 2PC。为此,Vitess 采用 Pre、Main、Post 三条连接按固定顺序提交/回滚,并通过加锁与事务编排来处理插入、删除、更新中的一致性问题。文章用删除后残留 orphan row、再次插入触发唯一键冲突等例子说明:即使 lookup 表短暂不一致,查询结果仍能保持与主表一致。它也明确了边界与限制,例如同值更新会产生锁等待,且同一事务内先删后插仍可能遇到该问题。

文章直接给出了 Vitess 一致性 lookup vindex 的提交顺序、锁定策略和失败恢复例子,属于可复用的分片一致性设计经验。适合做分库分表、MySQL 分片路由或数据库中间件设计参考,但其细节强依赖 Vitess 语义,落地时需注意同值更新和同事务删插的限制。

工程实践PlanetScale Blog

Summer 2023: Fuzzing Vitess at PlanetScale

文章记录作者在 PlanetScale 实习期间,为 Vitess 查询规划器设计随机 SQL fuzzing 的过程。团队先评估了 SQLancer,但由于 Vitess 需要尽量模拟 MySQL 且受 VSchema、分片键等约束,直接接入成本过高,最终转向自建生成器。生成器会从给定表集合中随机抽取表、列和表达式,覆盖 SELECT、WHERE、GROUP BY、ORDER BY、LIMIT 及派生表等场景,并把 Vitess 与 MySQL 的结果和错误逐条比对。作者还改造了查询简化器,使其能处理端到端测试所需的 VSchema 信息,并扩展表达式生成以支持列引用和受语义限制的聚合表达式。文章最后指出当前样例表和分片方案仍较固定,且部分已知失败查询依赖过滤开关,后续可通过随机化 schema/VSchema 和清理代码继续提升覆盖率。

收录理由明确:文章给出了在数据库查询规划器上做 fuzzing 的具体实现、与 SQLancer 的取舍、以及查询简化器和表达式生成器的改造细节。适合做数据库测试、查询优化器或模糊测试实践参考;其局限也清楚,当前覆盖仍受固定 schema 和分片模型限制。

技术文章PlanetScale Blog

Three common MySQL database design mistakes

这篇文章围绕 MySQL 数据库设计中的三个常见错误展开:字段类型选得过小或过大、索引缺失或冗余、以及半结构化数据存储方式不当。作者用一个车联网系统的真实案例说明,ID 列早期采用 INT 可能在业务增长后迅速逼近上限,最终甚至会威胁线上可用性;同时也举了 VARCHAR 过短导致写入失败、字段类型过宽造成额外存储浪费的例子。针对索引,文章解释了缺少索引会让大表查询退化为全表扫描,而过多或重复索引又会增加存储和写入维护成本。对于 JSON 数据,作者强调应优先使用 MySQL 原生 JSON 类型,而不是用 TEXT 直接存字符串,因为前者支持更高效的二进制存储、按字段查询和基于 JSON 内容建索引。结尾还提到通过把有符号整型回绕到负数区间临时扩容 ID 的权宜之计,并指出数据库设计必须结合增长预估和业务边界来权衡。

文章给出了字段类型、索引和 JSON 存储三个维度的具体反例与后果,不是泛泛而谈,而是能直接指导 MySQL 表结构设计和性能排查。适合后端开发、DBA 和做系统容量规划的读者参考,尤其对需要在增长、存储和写入成本之间做取舍的场景很有迁移价值。