问题现象
应用 SQL 偶发性执行耗时长,常见的有几个特征。
- SQL 语句整体相同,但是使用不同的查询条件过滤时,耗时抖动尤其明显。
- 人工执行正常,无法人工复现,一般是结合业务逻辑偶发出现。
- 如果是 java 应用,可能会出现 read time out 异常。
问题原因
一般是执行计划复用导致。
执行计划复用是指两条 SQL 如果只有过滤条件里面的常量值不同,数据库会使用同一个计划执行两条 SQL。由于不同参数过滤的数据量不同,会导致相同执行计划在不同过滤参数下执行时间不同,这是应用 SQL 偶发性执行耗时长的主要原因。要判断是否是执行计划复用引起,请按照如下步骤确认。
注意
请在问题发生后及时保存下面的信息,防止元数据表的数据被覆盖。
root 登录 sys 租户,执行如下 SQL 找到耗时抖动的 SQL 语句以及其
plan_id。select * from oceanbase.gv$sql_audit where query_sql like '%SQL语句关键字%' and query_sql not like '%sql_audit%' and elapsed_time>异常SQL执行耗时 order by request_time desc limit 4;根据
plan_id继续执行如下 SQL 过滤。select * from oceanbase.gv$sql_audit where plan_id=第一步的plan_id order by request_time desc;如果此条 SQL 的结果为多行返回,且异常 SQL 的
request_time并不是最小,可以定位是执行计划重用导致此类问题。根据
plan_id继续执行如下 SQL 查看执行计划相关信息。select * from oceanbase.gv$plan_cache_plan_stat WHERE plan_id=第一步的plan_id;关注
first_load_time列的时间,如果first_load_time早于异常 SQL 的request_time,也可以进一步确定执行计划重用导致此类问题。
解决方法
- 业务代码中使用 Hint 固定执行计划,推荐使用 Hint。
- OceanBase 数据库中使用 Outline 固定执行计划。
适用版本
OceanBase 数据库 V2.x 和 V3.x 版本。