---
title: 流量 SQL 场景使用 SPM 偶现抖动分析-OceanBase数据库使用指南
description: 了解OceanBase数据库在实际应用中关于 流量 SQL 场景使用 SPM 偶现抖动分析相关的常见问题和使用技巧，帮助您快速解决 流量 SQL 场景使用 SPM 偶现抖动分析的难题。
---
切换语言

- 简体中文
- English

划线反馈

# 流量 SQL 场景使用 SPM 偶现抖动分析

更新时间：2026-05-14 09:21

适用版本： V4.2.x、V4.3.x 内容类型：Troubleshoot  

## 问题现象

业务切流发现 SQL 偶尔会抖动，排查发现，执行计划不优，同时生成两个执行计划，抖动的 SQL 没有走索引，不走索引需要几十秒，走索引 2ms，一千多张表，很难通过绑定 outline，需要分析原因。

## 关键诊断信息

基本排查步骤如下。

1. 确定下索引是什么时间加的。

   ```shell
   SELECT t. create_time, s. index_name, s. table_name FROM information_schema. TABLES t JOIN information_schema.STATISTICS s ON t. table_name = s. table_name WHERE t. table_name = 'xxxxx';

   ```

   ![image01](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/knowledge-base/database/performance/20250722analysis-of-occasional-jitter-using-spm-in-traffic-sql-scenarios01.png)
 2. SQL 中加了这些字符指纹的东西，导致单个 SQL 流量就很低，很晚走索引的计划才进基线`（04-10 14:43:02）`，这个图能说明，走全表扫的计划 `2025-02-28` 都有了，索引是 3 月 7 号建的，因为单个 SQL 的流量太低，一直演进不完。

   ![image02](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/knowledge-base/database/performance/20250722analysis-of-occasional-jitter-using-spm-in-traffic-sql-scenarios02.png)

   ![image03](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/knowledge-base/database/performance/20250722analysis-of-occasional-jitter-using-spm-in-traffic-sql-scenarios03.png)

   ```shell
   ocp_monitor@[oceanbase]>select * from __all_virtual_plan_baseline_item where tenant_id = 1002 and sql_id = 'D1F3D1BE6F9BE7B417CA68A261A13C36'\G;
   *************************** 1. row ***************************
      tenant_id: 1002
    database_id: 534356
         sql_id: D1F3D1BE6F9BE7B417CA68A261A13C36
    plan_hash_value: 3233871342238735945
     gmt_create: 2025-04-10 14:43:02.151916
    gmt_modified: 2025-04-10 14:43:02.151916
       sys_vars: NULL
      plan_type: 1
    description: NULL
         origin: 1
     db_version: 4.2.5.2
    outline_data: /*+BEGIN_OUTLINE_DATA INDEX(@"SEL$1" "T1"@"SEL$1" "idx_user_out_biz_id") OPTIMIZER_FEATURES_ENABLE('4.2.1.10') END_OUTLINE_DATA*/
          flags: 27
    last_verified: 1744267358794134
    last_executed: 1744267358794134
    optimizer_cost: -1
     executions: 146
    elapsed_time: 109438
       cpu_time: 94827
     origin_sql: /* 2140eeb817442271795794636d10b2/0.5.9.33//34ecad1b/// */select `T1`.`id`,`T1`.`user_id`,`T1`.`user_nick`,`T1`.`other_user_id`,`T1`.`other_user_nick`,`T1`.`detail_id`,`T1`.`out_biz_id`,`T1`.`biz_type`,`T1`.`fc_type`,`T1`.`item_id`,`T1`.`biz_time`,`T1`.`deal_time`,`T1`.`p_trade_id`,`T1`.`trade_id`,`T1`.`quantity`,`T1`.`amount`,`T1`.`proration`,`T1`.`unpay_amount`,`T1`.`bill_cycle`,`T1`.`waiting_pay_date`,`T1`.`fc_user_bill_id`,`T1`.`status`,`T1`.`join_status`,`T1`.`extend_info`,`T1`.`own_sign`,`T1`.`version`,`T1`.`gmt_create`,`T1`.`gmt_modified`,`T1`.`error_message`,`T1`.`mirror_status`,`T1`.`mirror_id`,`T1`.`bill_type`,`T1`.`inner_type`,`T1`.`inner_id`,`T1`.`uk_biz_id`,`T1`.`is_delete`,`T1`.`db_remark`,`T1`.`quantity_d`,`T1`.`amount_d`,`T1`.`unpay_amount_d`,`T1`.`currency`,`T1`.`country`,`T1`.`proration_d`,`T1`.`term_inst_id` from `xxxxxx` `T1` WHERE ((`T1`.`user_id` = 776045324) AND (`T1`.`out_biz_id` = '13551627007075324') AND ((`T1`.`is_delete`) IS NULL OR (`T1`.`is_delete` = 0)))
    *************************** 2. row ***************************
      tenant_id: 1002
      database_id: 534356
         sql_id: D1F3D1BE6F9BE7B417CA68A261A13C36
      plan_hash_value: 11986391583431335905
      gmt_create: 2025-02-28 11:15:41.374811
      gmt_modified: 2025-04-10 14:47:13.245839
       sys_vars: NULL
      plan_type: 1
      description: NULL
         origin: 1
      db_version: 4.2.1.10
      outline_data: /*+BEGIN_OUTLINE_DATA FULL(@"SEL$1" "T1"@"SEL$1") OPTIMIZER_FEATURES_ENABLE('4.2.1.10') END_OUTLINE_DATA*/
          flags: 27
      last_verified: 1744265810828417
      last_executed: 1744265810828417
      optimizer_cost: -1
      executions: 4
      elapsed_time: 159435677
      cpu_time: 159434545
      origin_sql: /* 2102ea2017407125343051301d0174/9.17//34ecad1b/// */select `T1`.`id`,`T1`.`user_id`,`T1`.`user_nick`,`T1`.`other_user_id`,`T1`.`other_user_nick`,`T1`.`detail_id`,`T1`.`out_biz_id`,`T1`.`biz_type`,`T1`.`fc_type`,`T1`.`item_id`,`T1`.`biz_time`,`T1`.`deal_time`,`T1`.`p_trade_id`,`T1`.`trade_id`,`T1`.`quantity`,`T1`.`amount`,`T1`.`proration`,`T1`.`unpay_amount`,`T1`.`bill_cycle`,`T1`.`waiting_pay_date`,`T1`.`fc_user_bill_id`,`T1`.`status`,`T1`.`join_status`,`T1`.`extend_info`,`T1`.`own_sign`,`T1`.`version`,`T1`.`gmt_create`,`T1`.`gmt_modified`,`T1`.`error_message`,`T1`.`mirror_status`,`T1`.`mirror_id`,`T1`.`bill_type`,`T1`.`inner_type`,`T1`.`inner_id`,`T1`.`uk_biz_id`,`T1`.`is_delete`,`T1`.`db_remark`,`T1`.`quantity_d`,`T1`.`amount_d`,`T1`.`unpay_amount_d`,`T1`.`currency`,`T1`.`country`,`T1`.`proration_d`,`T1`.`term_inst_id` from `xxxxxx` `T1` WHERE ((`T1`.`user_id` = 4068257372) AND (`T1`.`out_biz_id` = '8097191880067372') AND ((`T1`.`is_delete`) IS NULL OR (`T1`.`is_delete` = 0)))
   2 rows in set (0.025 sec)

   ```

   查询演进的次数，3 小时累计不超过 150 次。

   ![image04](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/knowledge-base/database/performance/20250722analysis-of-occasional-jitter-using-spm-in-traffic-sql-scenarios04.png)
 3. 解决办法全表扫的基线计划删掉就解决了，后面这个 SQL 就不会生成全表扫的计划。（注意仔细检查 SQL 小心执行）

   ```shell
   SELECT dbms_spm.drop_sql_plan_baseline('global_hjbill_cold_backup_ob_0003' ,sql_id, plan_hash_value) FROM oceanbase.__all_plan_baseline_item WHERE tenant_id = 1002 AND outline_data LIKE '%FULL(@"SEL$1" "T1"@%' AND origin_sql LIKE '%hj_fc_bill%';

   ```

## 问题原因

问题的根本原因是由于 SQL 执行计划的生成差计划时间比较早，索引是之后创建的创建。首次计划生成时`（2025-02-28）`，还未建立索引，因此基线计划中只有全表扫描的基线。业务索引是在 3 月 7 日创建的，但由于单个 SQL 的流量非常低（单个 SQL 的流量非常低主要原因是 SQL 中有业务的 SQL 指纹随机值，3 小时内累计不超过 150 次），走索引的计划直到最近才进入基线客户才关注到。此外，由于 `SPM`（SQL Plan Management）海景计划演进过程中，即使新的计划更优，仍可能有部分流量选择旧的全表扫描计划来执行，这导致了性能的不稳定。

```shell
origin_sql: /* 2140eeb817442271795794636d10b2/0.5.9.33//34ecad1b/// */select

```

## 问题的风险及影响

全表扫描会导致查询速度显著变慢影响业务的正常运行。

## 适用版本

OceanBase 数据库 V4.2.1 GA（oceanbase-4.2.1.0-100000182023092722）版本、V4.2.5（oceanbase-4.2.5.0-100000082024102022）版本、V4.3.5（oceanbase-4.3.5.0-100000122024123020）版本。

## 解决方法

删除全表扫描的基线计划，使优化器能够选择更优的索引扫描计划。在 OceanBase 数据库 V4.2.5 BP2 版本中是如果 3 小时 150 次跑不到就认为演进失败。正在做的调整是取消了超时时间，只要计划没有淘汰能跑到 150 次 SPM 就会接管。

```shell
SELECT dbms_spm.drop_sql_plan_baseline ('global_hjbill_cold_backup_ob_0003' ,sql_id, plan_hash_value) FROM oceanbase.__all_plan_baseline_item WHERE tenant_id = 1002 AND outline_data LIKE '%FULL(@"SEL$1" "T1"@%' AND origin_sql LIKE '%hj_fc_bill%';

```

## 规避方式

1. 如果开启 SPM，在创建索引后，分析业务 SQL 适合走索引的计划，应该主动删除相关的旧的基线计划（`dbms_spm.drop_sql_plan_baseline`），避免 SPM 选择不优的计划。
 2. 对于流量较低的 SQL，定期检查并优化执行计划，确保其能够利用新创建的索引。

Previous

[如何获取表的直方图](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000004752489)

Next

[如何统计正在运行的事务](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000004409028) ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
