Query Optimizer

18 篇内容

技术文章SelectDB 技术分享

Apache Doris 高性能 Open Lake Variant 读写技术解析 面对日志、事件、AI 调用等不断变化的半结构化数据,如何既保留灵活结构,又实现高效查询?从 Doris 4.2 ...

Doris 4.2 起可在 Iceberg、Paimon 上直接读写 VARIANT 半结构化数据。文章分三层讲解:值由 metadata 字段名字典与 value 二进制编码,可按路径拆成类型子列,类型不匹配的值保留在 residual/fallback;读取按文件与 Row Group 选择叶子投影、残余补齐或完整投影,并结合统计裁剪;执行层保留 Encoded、Typed、Shredded 三种形态并延迟物化,避免重建完整对象。写回时 Iceberg 经 Arrow 生成 Parquet,Paimon 经 JNI 交给原生 writer,当前不回写拆列文件。测试称相比 Spark 冷跑 15.10×、热跑 19.14×,拆列热跑 58.64×,但 SQL 示例未在集群执行。

Doris 团队完整拆解了 Variant 的编码、拆列、按路径读取与延迟物化机制,并给出可观测的 Profile 指标和冷热跑对比数据,可作为湖仓半结构化数据格式设计与查询优化的参考。适合从事 OLAP/湖仓选型、Parquet 列裁剪与执行引擎优化的工程师阅读;需注意性能数字来自厂商自测、不含导入耗时,SQL 示例也未实机验证。

技术文章Greptime 技术

JSON Is No Longer a Blob: Inside GreptimeDB 1.2's New JSON Type

文章深入解析 GreptimeDB 1.2 新增的 JSON2 类型,针对传统 JSONB 按整文档存储、分析查询需读取并解析完整 JSON 的问题。其核心是有界自动 shredding:高频路径展开为独立列,并分为静态类型路径、预算内动态路径和 Parquet Variant 余量三层;查询时通过类型具体化从 SQL 推断所需结构类型,类型提示可固定路径类型并拒绝不匹配写入。结论是 JSON2 适合日志、trace 等可观测性场景,能按路径裁剪读取且保留原始嵌套;但冷路径仍需读余量,类型推断可能出错,自动展开有上限,1.2 中修改配置尚未正式支持。

推荐收录:文章不仅介绍功能,还给出 JSONB 与 JSON2 的读写差异、三层存储、类型具体化、类型提示和完整 SQL 示例,并引用 JSONBench 数据说明边界。适合数据库、存储引擎、可观测性平台工程师理解半结构化数据的列式化设计;可迁移到日志/trace 分析中的路径裁剪、列式存储和类型约束设计,但需留意冷路径读取与类型推断错误风险。

技术文章Greptime 技术

JSON Is No Longer a Blob: Inside GreptimeDB 1.2's New JSON Type

文章解析 GreptimeDB 1.2 新增的 JSON2 类型,面向日志、Trace 等路径繁多但查询只访问少数路径的 JSON 数据。传统 JSONB 按整文档存储,读一个字段也需扫描和解析完整文档,索引无法消除这类 I/O 与 CPU 放大。JSON2 采用有界自动 shredding,将热路径展开为独立 Parquet 列,长尾写入 Parquet Variant remainder,并支持 type hints 固定类型;查询端通过 query type concretization 从 SQL 推导结构化类型,实现列裁剪与向量化执行。局限是类型推断依赖 SQL 表达式,写错可能返回无意义结果,且 1.2.x 不能修改已有 JSON2 配置。该方案适合可观测性分析,但冷路径仍需读 remainder,自动展开预算默认 100。

推荐收录。文章基于 GreptimeDB 1.2.1 的真实实现,清晰给出 JSONB 整文档读放大、JSON2 有界 shredding、Parquet Variant remainder、query type concretization 与 type hints 的设计细节和 SQL 示例,并明确说明类型推断错误、冷路径成本和 1.2.x 配置不可变等边界。适合数据库内核、存储引擎和可观测性平台开发者参考,其“热路径列化+长尾归并+查询驱动类型推导”的取舍可迁移到其他半结构化分析系统。

工程实践TiDB 社区博客 - 实践案例

TiDB SQL 调优实战:从”跑不动”到”飞起来”的三个真实案例

文章以TiDB生产环境中的三个真实SQL调优案例为主线,展示从“跑不动”到“飞起来”的完整排查过程。第一个案例是因统计信息过期导致优化器误判筛选率,未走联合索引的最优范围,通过ANALYZE和配置自动收集恢复性能;第二个案例是分区表查询因NOW()等非常量表达式导致分区裁剪失效,改写为常量时间后恢复正常;第三个案例是自增主键在聚簇索引下形成写热点,通过AUTO_RANDOM或业务主键加预分裂分散写入。每个案例都给出根因判断、优化SQL和执行计划变化,并总结出先看执行计划、重视统计信息、预防写热点三条方法论,附有诊断命令速查。边界在于案例基于TiDB特定实现,部分结论对传统单机数据库不一定适用。

推荐收录。文章不是零散技巧,而是围绕具体线上问题的诊断链路:现象、根因定位、方案验证和预防措施都写得很清楚,适合TiDB/分布式数据库运维和SQL调优读者。文中关于统计信息、分区裁剪、写入热点的分析方法可迁移到其它分布式或关系型数据库,只是需要结合各自引擎特性试用。

工程实践DuckDB Engineering Blog

How DuckDB Runs Recursive CTEs Faster

本文来自 DuckDB 工程博客,介绍了 v2.0 对递归 CTE 执行引擎的重构,目标是消除迭代间重复调度与重建状态的开销。核心方法是将物理算子树、预计算调度投影和可复用执行器池归查询计划所有,递归调用持有跨 epoch 的不变状态(如基于静态表构建的哈希表),每个 epoch 仅重置依赖前沿的状态,并通过精确的边界基数选择内联或并行调度。针对 USING KEY 递归,冻结键控状态以支持直接探测,内连接可用 RECURSIVE_KEY_JOIN 或部分键索引,并引入语义变化:UNION 仅转发最终发生变化的键,UNION ALL 仍转发全部候选。实验显示,在 100 万边可达性查询中延迟从 4.051 秒降至 0.095 秒,LDBC SF100 路径查询提速 6.55 倍且峰值内存下降,63 个递归基准几何均值改善 5.5%。适用边界包括:保留状态需可重复性证明,预聚合要求聚合状态可组合且无顺序依赖,宽唯一键更新场景有约 6% 的回归。

直接证据是作者为 DuckDB 核心开发者,提供了 PR 编号、EXPLAIN 分析与中位数基准对比,且讨论了语义变化与回归。适合数据库内核开发者、查询引擎研究者与对 SQL 递归性能优化感兴趣的读者。可迁移价值在于状态所有权划分、基于实测基数的自适应执行和变更键去重思想;风险是部分语义变更(UNION 改变行为)需使用者注意。

技术文章ClickHouse Engineering

ClickHouse Release 26.7

文章是 ClickHouse 26.7 版本发布说明,主体是对查询执行与向量检索内部优化的解析。它把按序聚合与新增的 limit 下推融合,使 GROUP BY…ORDER BY…LIMIT 成为可提前终止的流式流水线;JOIN 新增构建键驱动的探测端 granule 裁剪、哈希表行引用压缩与 dpsub 连接顺序算法;QBit 引入 Int8 量化、跨步存储、Hadamard 旋转与量化编解码器。文中用 TPC-H 与 HackerNews 数据集给出基准,称 Top-N 提速 313 倍、峰值内存降 592 倍,JOIN 提速 6.2 倍。还简述短语位置索引、EXPLAIN ANALYZE、Remote 引擎和 URL 统一等特性,并标注部分能力为实验性。

推荐收录:虽为版本发布说明,但每项优化都给出机制解释(如按序聚合与 LIMIT 下推融合、运行期过滤器驱动 granule 裁剪)和可复现的 TPC-H/HackerNews 基准,属于有边界、可验证的工程性能证据。适合数据库内核、OLAP 查询优化与向量检索方向读者;排序键前缀聚合、构建侧过滤下推等思路可迁移。主要风险是性能倍数依赖特定数据集与硬件,不宜直接外推。

技术文章DuckDB Engineering Blog

A Preview of DuckDB v2.0

DuckDB v2.0预览文章由核心开发者撰写,概述了即将发布的重大版本的主要特性。文章首先介绍了DuckDB作为服务器的新模式,通过Quack协议和CONNECT语句实现客户端/服务器架构,支持远程查询生产数据库。随后重点讲解了VARIANT类型的深化应用,使其能高效处理半结构化数据,并配合一系列variant_*函数。文章还介绍了触发器、丰富SQL方言(如NEAREST连接、CTE内DML、嵌套schema等)、全引擎异步I/O、大量查询性能优化(如重写递归CTE、聚合下推、分区感知规划)、新存储格式、全新PEG解析器,以及用自研实现替代ICU库带来的体积和性能优势。最后强调了稳定C API和自定义扩展仓库,使扩展编写和分发更加便捷。文章以预览形式呈现,强调细节可能在正式发布前调整,并提到部分破坏性变更。

本文是DuckDB官方工程博客的权威技术预览,内容详实,包含具体代码示例、性能基准和设计动机,展示了嵌入式数据库向客户端/服务器模式演进的关键架构决策。适合数据库内核工程师、数据分析平台开发者和对查询引擎优化感兴趣的读者。文中关于异步I/O、存储格式演进和扩展稳定ABI的设计思想具有可迁移性,但需注意各功能为预览状态,正式发布可能调整。

技术文章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 替代方案。需要注意的是测试仅基于单节点和特定数据集,索引列选择需按业务权衡。

工程实践ClickHouse Engineering

What's new in pg_clickhouse v0.10.0: Subqueries, TPC-H Speedups, C Driver, and Aggregates

文章介绍 pg_clickhouse v0.10.0 的更新,重点是扩大 PostgreSQL 查询向 ClickHouse 下推的范围。作者以 TPC-H 为度量,将完全下推的查询从 22 条中的 12 条提升到 16 条;Q17 从 32.7 秒降至 37 毫秒,并快于原生 PostgreSQL 的 2.1 秒。技术核心是把相关子查询与 NOT IN 下推为半连接/反连接,同时用额外空值守卫弥合 PostgreSQL 三值逻辑与 ClickHouse 二值逻辑在 NULL 上的语义差异。工程侧还改用 clickhouse-c 重写 C 驱动,统一 HTTP 与二进制 Native 协议,修复并发扫描连接冲突,并扩展统计聚合、有序集聚合和分区聚合下推。文章明确仍剩 6 条 TPC-H 查询未下推,受限于 join tree 两侧遍历,且相关子查询要求 ClickHouse 25.8 以上,否则回退本地执行。

推荐收录:文章不仅列出 pg_clickhouse 新功能,还给出可验证的 TPC-H 性能改进(Q17 32.7s→37ms)、三值/二值逻辑差异导致的正确性陷阱及守卫实现,以及驱动层从 C++ 到 C 的架构权衡和并发修复。对使用 PostgreSQL FDW、构建异构数据库查询下推、OLAP 加速或数据库扩展开发的工程师具有直接参考价值,其语义兼容性验证思路可迁移到其他数据源集成场景。

工程实践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 和做系统容量规划的读者参考,尤其对需要在增长、存储和写入成本之间做取舍的场景很有迁移价值。