当前位置: 首页 > news >正文

隐含参数 _b_tree_bitmap_plans 导致 SQL 执行计划劣化

问题现象:同一关键 SQL,一厂平均执行 12ms,三厂平均执行 700ms(三厂数据量更小)

根因:三厂数据库设置了隐含参数 _b_tree_bitmap_plans=FALSE,禁用了 BITMAP CONVERSION TO ROWIDS 访问路径,优化器退化为全表扫描

解决方案:通过 SQL Profile 为三厂绑定含 BITMAP CONVERSION 的较优执行计划,执行时间降至 1ms 以内

1. 问题现象

业务反馈某个关键 SQL 在一厂和三厂的执行时间差距较大。三厂数据量更小,理论上应该更快,但实际表现相反。

1.1 执行时间对比

工厂

平均执行时间

执行计划

一厂

~12ms

BITMAP CONVERSION TO ROWIDS(索引访问)

三厂

~700ms

FULL TABLE SCAN(全表扫描)

1.2 执行计划差异

一厂执行计划

三厂执行计划

关键差异访问路径就是一厂走的BITMAP 三厂走的全表

2. 根因分析

2.1 关键参数

三厂为新建工厂,数据库实施参数标准中配置了隐含参数_b_tree_bitmap_plans = FALSE。该参数在 OLTP 最佳实践中建议设为 FALSE,但在本案例中恰好阻止了优化器选择最优执行计划。

参数说明:_b_tree_bitmap_plans 控制优化器是否考虑 BITMAP CONVERSION TO ROWIDS / FROM ROWIDS 以及 BITMAP AND/OR/MINUS 等执行计划。

默认为TRUE(允许),设为FALSE后所有 B-tree 索引转 Bitmap 的访问路径均被禁用。

2.2 影响链路

一厂执行计划访问路径

h := SYS.SQLPROF_ATTR( q'[BEGIN_OUTLINE_DATA]', q'[IGNORE_OPTIM_EMBEDDED_HINTS]', q'[OPTIMIZER_FEATURES_ENABLE('19.1.0')]', q'[DB_VERSION('19.1.0')]', q'[OPT_PARAM('_optimizer_extended_cursor_sharing' 'none')]', q'[OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none')]', q'[OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false')]', q'[OPT_PARAM('_optimizer_use_feedback' 'false')]', q'[OPT_PARAM('_optimizer_gather_feedback' 'false')]', q'[ALL_ROWS]', q'[OUTLINE_LEAF(@"SEL$1")]', q'[OUTLINE_LEAF(@"SEL$2")]', q'[NO_ACCESS(@"SEL$2" "from$_subquery$_002"@"SEL$2")]', q'[BITMAP_TREE(@"SEL$1" "LX"@"SEL$1" OR(1 1 ("TEST"."SN") 2 ("TEST"."SUBSN") 3 ("TEST"."XPSN")))]', q'[BATCH_TABLE_ACCESS_BY_ROWID(@"SEL$1" "LX"@"SEL$1")]', q'[END_OUTLINE_DATA]'); :signature := DBMS_SQLTUNE.SQLTEXT_TO_SIGNATURE(sql_txt); :signaturef := DBMS_SQLTUNE.SQLTEXT_TO_SIGNATURE(sql_txt, TRUE);

三厂执行计划访问路径

h := SYS.SQLPROF_ATTR( q'[BEGIN_OUTLINE_DATA]', q'[IGNORE_OPTIM_EMBEDDED_HINTS]', q'[OPTIMIZER_FEATURES_ENABLE('19.1.0')]', q'[DB_VERSION('19.1.0')]',q'[OPT_PARAM('_b_tree_bitmap_plans' 'false')]', --该隐含参数阻止了优化器选择BITMAPq'[OPT_PARAM('_optim_peek_user_binds' 'false')]', q'[OPT_PARAM('_bloom_filter_enabled' 'false')]', q'[OPT_PARAM('_optimizer_extended_cursor_sharing' 'none')]', q'[OPT_PARAM('_optimizer_outer_to_anti_enabled' 'false')]', q'[OPT_PARAM('_bloom_pruning_enabled' 'false')]', q'[OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none')]', q'[OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false')]', q'[OPT_PARAM('_and_pruning_enabled' 'false')]', q'[OPT_PARAM('_optimizer_use_feedback' 'false')]', q'[OPT_PARAM('_px_adaptive_dist_method' 'off')]', q'[OPT_PARAM('_optimizer_strans_adaptive_pruning' 'false')]', q'[OPT_PARAM('_optimizer_null_accepting_semijoin' 'false')]', q'[OPT_PARAM('_optimizer_gather_feedback' 'false')]', q'[OPT_PARAM('_optimizer_reduce_groupby_key' 'false')]', q'[OPT_PARAM('_optimizer_nlj_hj_adaptive_join' 'false')]', q'[ALL_ROWS]', q'[OUTLINE_LEAF(@"SEL$1")]', q'[OUTLINE_LEAF(@"SEL$2")]', q'[NO_ACCESS(@"SEL$2" "from$_subquery$_002"@"SEL$2")]', q'[FULL(@"SEL$1" "LX"@"SEL$1")]', q'[END_OUTLINE_DATA]'); :signature := DBMS_SQLTUNE.SQLTEXT_TO_SIGNATURE(sql_txt); :signaturef := DBMS_SQLTUNE.SQLTEXT_TO_SIGNATURE(sql_txt, TRUE);

2.3 为何 OLTP 建议设为 FALSE

该参数设为 FALSE 的初衷是避免 OLTP 场景下产生不合适的 Bitmap 转换计划。当 SQL 包含多个 B-tree 索引条件(尤其是星型转换、多索引 AND/OR,本案例sql为多个or查询)时,优化器可能生成次优的 BITMAP CONVERSION 计划。此外,19c 中存在已知 Bug:

  • Bug 30102774— ORA-7445 [kkosbn] Error With SQL With Bitmap Plans

设为 FALSE 可作为 workaround 规避该类 Bug。但对于需要使用 BITMAP CONVERSION 的特定 SQL,该设置会产生负面影响。

3. 解决方案

3.1 方案选择

最简单且影响最小的方式是使用SQL Profile为该 SQL 绑定含 BITMAP CONVERSION 的较优执行计划,无需修改全局参数,不影响其他 SQL 的执行计划。

3.2 一厂 SQL Profile Outline(较优计划)

从一厂获取该 SQL 的较优执行计划 Outline,通过 SQL Profile 绑定到三厂。关键 Hint 如下:

  • BITMAP_TREE(@"SEL$1" "LX"@"SEL$1" OR(1 1 ("TEST"."SN") 2 ("TEST"."SUBSN") 3 ("TEST"."XPSN")))

  • BATCH_TABLE_ACCESS_BY_ROWID(@"SEL$1" "LX"@"SEL$1")

一厂 Outline 中包含的优化器参数绑定:

  • OPT_PARAM('_optimizer_extended_cursor_sharing' 'none')

  • OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none')

  • OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false')

  • OPT_PARAM('_optimizer_use_feedback' 'false')

  • OPT_PARAM('_optimizer_gather_feedback' 'false')

3.3 三厂当前 SQL Profile Outline(较差计划)

三厂执行计划 Outline 中包含的关键差异:

  • OPT_PARAM('_b_tree_bitmap_plans' 'false')— 直接导致无法使用 BITMAP CONVERSION

  • FULL(@"SEL$1" "LX"@"SEL$1")— 全表扫描(替换了 BITMAP_TREE)

此外还包含以下参数绑定:

  • OPT_PARAM('_optim_peek_user_binds' 'false')

  • OPT_PARAM('_bloom_filter_enabled' 'false')

  • OPT_PARAM('_bloom_pruning_enabled' 'false')

  • OPT_PARAM('_and_pruning_enabled' 'false')

  • OPT_PARAM('_optimizer_outer_to_anti_enabled' 'false')

  • OPT_PARAM('_optimizer_null_accepting_semijoin' 'false')

  • OPT_PARAM('_optimizer_reduce_groupby_key' 'false')

  • OPT_PARAM('_optimizer_nlj_hj_adaptive_join' 'false')

  • OPT_PARAM('_px_adaptive_dist_method' 'off')

  • OPT_PARAM('_optimizer_strans_adaptive_pruning' 'false')

3.4 效果验证

阶段

执行计划

平均执行时间

优化前(三厂原始)

FULL TABLE SCAN

~700ms

一厂参考值

BITMAP CONVERSION TO ROWIDS

~12ms

优化后(绑定 SQL Profile)

BITMAP CONVERSION TO ROWIDS

小于 1ms

绑定 SQL Profile 后,三厂该 SQL 的执行时间从 700ms 降至 1ms 以内,性能提升约700 倍

4. _b_tree_bitmap_plans 参数详解

4.1 控制范围

该隐藏参数控制优化器是否考虑以下执行计划:

  • BITMAP CONVERSION TO ROWIDS

  • BITMAP CONVERSION FROM ROWIDS

  • BITMAP AND / OR / MINUS

这类 B-tree 索引转 Bitmap 再运算的执行计划。

4.2 参数值说明

参数值

行为

TRUE(默认)

允许优化器使用 BITMAP CONVERSION 相关计划

FALSE

禁止所有 BITMAP CONVERSION 计划,不再出现 BITMAP CONVERSION TO ROWIDS 等路径

4.3 典型执行计划场景

当 SQL 包含多个 B-tree 索引条件(尤其是星型转换、多索引 AND/OR)时,优化器可能生成如下计划:

  • BITMAP CONVERSION TO ROWIDS

  • BITMAP AND

  • BITMAP CONVERSION FROM ROWIDS - INDEX RANGE SCAN

  • BITMAP CONVERSION FROM ROWIDS - INDEX RANGE SCAN

将 _b_tree_bitmap_plans 设为 FALSE 后,上述计划全部被禁用。

4.4 查看与修改

  • 查看当前值:

  • select x.ksppinm name, y.ksppstvl value, y.ksppstdf isdefault, decode(bitand(y.ksppstvf, 7), 1, 'MODIFIED', 4, 'SYSTEM_MOD', 'FALSE') ismod, decode(bitand(y.ksppstvf, 2), 2, 'TRUE', 'FALSE') isadj from sys.x$ksppi x, sys.x$ksppcv y where x.inst_id = userenv('Instance') and y.inst_id = userenv('Instance') and x.indx = y.indx and x.ksppinm like '%b_tree_bitmap%' order by translate(x.ksppinm, ' _', ' ');
  • 会话级测试:ALTER SESSION SET "_b_tree_bitmap_plans" = FALSE;

  • Hint方式禁用/启用:

    SELECT /*+ OPT_PARAM('_b_tree_bitmap_plans', 'TRUE') */ SELECT /*+ OPT_PARAM('_b_tree_bitmap_plans', 'FALSE') */
  • 实例级修改(需重启):ALTER SYSTEM SET "_b_tree_bitmap_plans" = FALSE SCOPE=SPFILE;

5. 经验总结

1. 参数标准不能一刀切

OLTP 最佳实践中建议禁用 _b_tree_bitmap_plans 以规避已知 Bug 和次优计划,但需评估业务 SQL 是否依赖 BITMAP CONVERSION 路径。新建工厂实施参数标准时,建议先用一厂的执行计划基线做回归测试。

2. SQL Profile 是精准调优利器

当全局参数调整会影响其他 SQL 时,SQL Profile 可以针对单条 SQL 绑定最优执行计划,影响范围最小。适合「大部分 SQL 正常,个别 SQL 受影响」的场景。

3. 隐含参数变更需评估影响面

修改隐含参数前,建议在测试环境对关键 SQL 做执行计划对比(explain plan / SQL Tuning Advisor),确认不会产生回归。

http://www.jsqmd.com/news/1293801/

相关文章:

  • # [特殊字符]️ 嵌入式调试从入门到进阶 —— ARM 架构(二)
  • 使用.NET实现Word文档自动化生成与排版
  • Win11Debloat:Windows系统优化的模块化架构实践
  • iOS应用HTTPS安全策略配置指南:从ATS到证书锁定的实战解析
  • 做视频内容总结选什么AI工具?听脑AI vs 通义听悟真实对比 - AI办公提效专家
  • ESP32 Arduino下载速度慢?三招提速方案让烧录飞起来
  • 制造运营管理(MOM)与MES的区别与联系
  • TabPFN:基于Transformer架构的表格数据基础模型,实现1秒内的小型表格分类与回归推理
  • ErrorMiddleware在gin中间件放前还是后
  • Perlin Noise柏林噪声:从梯度噪声原理到程序化生成实践
  • 广州欧亚康体:商用泳池水处理一站式方案 - 城刊速递
  • 5分钟上手:Java APK解析器的完整使用指南
  • 人防工程防水堵漏工程十大综合口碑榜单,备选新人精选攻略不踩坑 - 工业品网
  • 2026主流三维测力台厂家推荐 适配不同场景需求 - 资讯速览
  • Flutter、Tauri与Electron跨平台开发框架对比
  • 焊接符号讲解
  • Python在芯片健康评估中的实战应用
  • 终极风扇控制指南:用Fan Control打造完美静音电脑
  • 垂直AI vs通用AI:生物医药该怎么选?
  • ffmpeg静态二进制文件:跨平台多媒体处理的终极解决方案
  • 离散制造行业MOM系统落地实施指南:从规划到上线的全流程解析
  • 2026年8月果洛非急救救护车转运指南:重症返乡如何安排 - 小校长
  • Ollama公网暴露实战检测:攻击面拆解、漏洞复现与全套加固方案
  • 基于启发式搜索的最优路径规划算法研究7
  • SNARF-5F荧光探针:高精度pH测量的生物医学突破
  • 免费在线地图编辑器GeoJSON.io:5分钟快速上手的终极地理数据可视化工具
  • 2026年上海网站设计公司推荐:10家实力派服务商核心能力解析 - 资讯速览
  • Java继承关系判断:isAssignableFrom方法与4种实现对比
  • 户外遮阳经销商联系指南:爱大树一体化服务解析 - 城刊速递
  • 【单片机毕设案例分享】基于权限校验的 STM32 电子密码锁系统设计 基于单片机输入校验的智能防盗门锁设计(012501)