首批通过分布式安全可靠测评,为关键业务系统打造
优化器无法准确评估包含 LOB 列访问的 SQL 执行代价导致计划选错
更新时间:2026-07-06 08:36
在数据库中 LOB(Large Object)类型是一种用于存储大容量数据的数据类型,通常用于存储文本、图像、音频、视频等非结构化数据。 当前 OceanBase 对于包含 LOB 列的查询 SQL,优化器不能准确的计算访问 LOB 列的代价,会导致计划代价计算和实际执行的时间不符或者是代价估计偏差大,从而导致基表计划选择不优的情况。 Oceanbase 当前包含的 LOB 类型,可参考 LOB 类型。
详细说明
LOB 字段的问题在于存储的数据量大小不一(根据 ob_inrow_threshold 的设置,查询 LOB 列字段,同时存在 OUTROW 访问的可能性),因此很难用一个有效的参数去描述。优化器只能给一个较大的评估值来避免差的计划。但是无法保证是当前数据下的最优计划。 如下面的查询中,可以看到查询包含 LOB 列的情况下,表 FULL SCAN 扫描的预估时间和实际执行时间相差很多(175747us vs 9886us)。 而当去掉 LOB 列,查询表 FULL SCAN 的时候,估算时间和预估时间比较接近。
第一部分执行计划(存在 LOB ):
*************************** 1. row ***************************
dbms_xplan.display_cursor(0, 'all'): ====================================================================================================
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|REAL.ROWS|REAL.TIME(us)|IO TIME(us)|CPU TIME(us)|
-------------------------------------------------------------------------------------------------------------------------------
|0 |MERGE GROUP BY | |1 |175764 |1 |9886 |0 |573 |
|1 |└─TABLE FULL SCAN |bfip_inventory_account |878 |175747 |12121 |9886 |0 |10480 | <<----- 存在 LOB
===================================================================================================
第二部分执行计划(去掉 LOB ):
dbms_xplan.display_cursor(0, 'all'): ====================================================================================================
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|REAL.ROWS|REAL.TIME(us)|IO TIME(us)|CPU TIME(us)|
----------------------------------------------------------------------------------------------------------------------------------------
|0 |MERGE GROUP BY | |1 |28297 |1 |44378 |0 |389 |
|1 |└─TABLE RANGE SCAN |bfip_inventory_account(idx_bfip_inventory_account_6)|7103 |28168 |12121 |44378 |0 |43647 | <<----- 去掉 LOB
===================================================================================================
因此对于包含 LOB 列的查询,可以尽量找到合适的计划,绑定对应的计划。
适用版本
OceanBase 数据库 V4.x 版本。