OceanBase 采用了 LSM tree 架构,将数据分为基线数据(major sstable)和增量数据(minor sstable、mini sstable、memTable),其中只有基线数据中不含有多版本数据,故 Delete、Update 产生的增量更新行会长时间存在,直到每日合并结束。在这期间,若表存在删除和更新,则实际物理扫描的数据和预期逻辑扫描的数据将会存在偏差。
特别的,如果业务将某张表作为缓存空间(buffer 表),数据在 Insert 进来后很快被 Delete,或是进行了批量的 Delete、Update,就会产生大量的增量多版本数据,影响 SQL 各个算子的估行,最终导致执行计划走偏性能退化,即发生了 buffer 表问题导致的 SQL 性能不优。
可以通过查看 SQL 的逻辑执行计划下的 Optimization Info 来简单判断一张表是否有 buffer 表问题,其会打印表扫描算子对表预估的扫描行数,physical_range_rows 包含了增量数据,会将 Delete 行也计算涵盖,而 logical_range_rows 不包含增量数据,是预期会扫描的逻辑行数,若两者偏差过大,则说明该表可能有 buffer表问题。
例如以下 SQL 逻辑执行计划:
Optimization Info:
-------------------------
J:
table_rows:4429840
physical_range_rows:13362167
logical_range_rows:4502487
index_back_rows:0
output_rows:0
table_dop:1
dop_method:DAS DOP
avaiable_indeX_name:[PK_TD_WBILL_DETAIL_JOUR, TD_WBILL_DETAIL_JOUR]
stats version:1761919246364701
dynamic sampling level:0
该表预估只有 442 万行,预估逻辑扫描 450 万行,但预估物理扫描 1336 万行,相差 3~4 倍,可以怀疑发生了严重的 buffer 表问题。 此时可以尝试进行一次合并来解决,也可以尝试将该表改为 queuing 表后进行一次转储。
总结
可以通过逻辑执行计划中输出的 physical_range_rows 与 logical_range_rows 来快速简单判断一张表是否存在 buffer 表问题。
适用版本
OceanBase 数据库 V4.x 版本