跳到主要内容

查询优化器介绍

一句话定义

Doris 查询优化器(Nereids)是基于 Cascades 框架构建的现代化查询优化器,通过 RBO(基于规则的优化)与 CBO(基于成本的优化)相结合,为复杂查询生成高效的执行计划。

阅读速览

在阅读本文前,建议先了解以下内容:

  • 查询优化器在数据库系统中的基本作用
  • SQL 执行计划的基本概念
  • 基于规则优化(RBO)与基于代价优化(CBO)的区别

本文将依次介绍:

  • 查询优化器的研发背景
  • Doris 查询优化器的核心优势
  • 优化器的整体工作原理
  • 常用调优会话变量

研发背景

当前的查询优化器面临三类挑战:

挑战具体表现
查询复杂度高用户的查询语句日益复杂,查询场景日益多样化
实时性要求严用户期望即时获取查询结果
迭代速度快需要快速适配不断出现的新需求

基于以上背景,Doris 启动了全新查询优化器的研发。该优化器依托现代优化器架构,旨在更高效地处理 Doris 场景下的查询请求,并为未来更复杂的需求提供良好的扩展基础。

Doris 查询优化器优势

Doris 查询优化器在「智能、稳定、灵活」三个维度上相较于旧优化器具备显著优势。

更聪明

  • 优化器将每个 RBO 与 CBO 的优化点以「规则」的形式清晰呈现。
  • 每条规则都提供了一组用于描述查询计划形状的模式,能够精确匹配可优化的查询计划。
  • 因此,优化器能够更好地支持多层子查询嵌套等复杂查询语句。

CBO 部分基于先进的 Cascades 框架,充分利用以下三类信息:

  1. 丰富的数据统计信息
  2. 数据特征信息
  3. 精心调优的代价模型

借助这些信息,优化器在处理多表 Join 等复杂查询时能够游刃有余。

更稳定

  • 所有优化规则均在逻辑执行计划树上完成。
  • 查询语法语义解析完成后,会被转换为树状结构。
  • 相比旧优化器,新优化器的内部数据结构更加合理、统一。

以子查询处理为例:新优化器基于新的数据结构,避免了旧优化器中众多规则对子查询的单独处理,从而降低了优化规则出现逻辑错误的可能性。

更灵活

优化器的架构设计合理且现代,扩展优化规则与处理阶段非常方便,能够快速增加新功能以满足不断变化的需求。

优化器工作原理

整体流程

优化器工作原理

优化器的执行流程大致分为以下四个步骤:

步骤阶段说明
1语法分析将 SQL 文本转换为抽象语法树(AST)。SQL 合法则继续,非法则报错并终止
2语义分析检查 AST 中表、列、函数等的存在性以及使用是否符合语法和语义规则。合法则继续,非法则报错并终止
3改写查询计划(RBO)通过预定义的规则对查询计划进行改写,常见手段包括列裁剪、谓词下推、分区裁剪等
4优化查询计划(CBO)在搜索空间中枚举等价的计划集合,评估各计划的执行代价,选择代价最小的计划作为最终执行计划

各步骤的目标如下:

  • 语法分析:确保 SQL 文本可被解析为合法的 AST。
  • 语义分析:确保 AST 中引用的对象存在且使用方式合法。
  • RBO 改写:通过确定性规则优化执行速度。
  • CBO 优化:基于代价模型选择最优执行计划,确保查询以最高效的方式执行。

常用会话变量

nereids_timeout_second

内容
作用设置查询规划的最大允许时间。规划时间超过该值时,规划将被终止并返回错误信息
默认值30s
适用场景查询涉及大量外部表,或查询语句特别复杂时,可适当增加该值以确保查询正常进行

设计目的:在规划查询语句的过程中,系统会获取 SQL 涉及的所有表的读锁。设置超时机制的主要目的是:

  • 维护集群的稳定性
  • 防止规划时间过长造成资源过度占用
  • 避免锁冲突问题

调优建议

  • 当出现规划超时错误时,先排查 SQL 是否过于复杂或表数量过多。
  • 如确认是合理场景,可通过 SET nereids_timeout_second = <秒数>; 调大该值。