验证与分享执行计划突变引发的问题

作者简介

张瑞远,曾经从事银行、证券数仓设计、开发、优化类工作,现主要从事电信级IT系统及数据库的规划设计、架构设计、运维实施、运维服务、故障处理、性能优化等工作。 持有Orale OCM,MySQL OCP及国产代表数据库认证。 获得的专业技能与认证包括 OceanBase OBCE、Oracle OCP 11g、OracleOCM 11g 、MySQL OCP 5.7 、腾讯云TBase、腾讯云TDSQ

背景:

由于之前遭遇过执行计划突变引发的集群问题,我们已经实施了相应的监控措施和手段。接下来,我将对这些现象及其原理进行简要验证和分享。

扩展分享:

1. OceanBase 在4.0增加了cursor_sharing参数

这个参数的主要作用是确认在处理SQL时是否实施参数化。在OceanBase的早期版本中,默认会对某些常量进行参数化处理,这样可以使多个含有不同参数的sql语句复用相同的执行计划,从而降低解析成本。然而,对于存在数据倾斜的情况,这种处理方式有时会导致选择错误的执行计划。对于这个问题的深入探讨,我会在后续内容中详细展开。同时,我也与白鳝老师进行了交流并请教了相关问题,大家也可以参考白鳝老师的公众号以获取更多信息。

2. OceanBase在4.x提升对于pl的一些优化

我做了个很简单的测试,因为本篇不是主要探究这个事情,简单介绍下让大家知道,在ob的3.x版本可以理解是有两套sql引擎,一套火山模型一套向量模型(4.x只有一套代码使用向量引擎,在3.x做过度),所以大部分pl在3.x还是走的老引擎,sql有些触发bug的情况下也会走到老引擎(这个问题很少见在3.x前期版本遇到过),对于匿名块可以看到sql aduit是没有sqlid的,plan cache里也查不到,是不缓存的,也就是匿名块每次都是硬解析。当然我在4.2.1版本测试plan cache里也是没有缓存的,但是已经有sqlid了,应该后续产品会把这块完善。

obclient [ACCOUNT]> DECLARE    query_2 VARCHAR2(200) := 'SELECT * from OB_PLAN_TEST1 where DDID = :x';    a number :=1;   BEGIN     while a=1 LOOP execute immediate query_2 USING  '370623.122717135116785630990292275519114'; a:=a+1; DBMS_OUTPUT.PUT_LINE(a||'完成');     end loop; END;/
Query OK, 1 row affected (0.058 sec)2完成
obclient [ACCOUNT]> DECLARE    query_2 VARCHAR2(200) := 'SELECT * from OB_PLAN_TEST1 where DDID = :x';    a number :=1;   BEGIN     while a=1 LOOP execute immediate query_2 USING  '370623.122717135116785630990292275519114'; a:=a+1; DBMS_OUTPUT.PUT_LINE(a||'完成');     end loop; END;/
Query OK, 1 row affected (0.053 sec)2完成MySQL [oceanbase]> select /*+parallel(32)*/ sql_id,usec_to_time(request_time),svr_ip,plan_id,params_value,query_sql,plan_type,ELAPSED_TIME from gv$ob_sql_audit where query_sql like '%DECLARE%' order by request_time limit 50;
+----------------------------------+----------------------------+----------------+---------+--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------+--------------+
| sql_id                           | usec_to_time(request_time) | svr_ip         | plan_id | params_value | query_sql                                                                                                                                                                                                                                                                 | plan_type | ELAPSED_TIME |
+----------------------------------+----------------------------+----------------+---------+--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------+--------------+
| D62BAB1A05D83614534EF5260991A487 | 2023-12-04 14:44:01.209444 | 172.16.100.137 |       0 |              | DECLARE    query_2 VARCHAR2(200) := 'SELECT * from OB_PLAN_TEST1 where DDID = :x';    a number :=1;   BEGIN     while a=1 LOOP execute immediate query_2 USING  '370623.122717135116785630990292275519114'; a:=a+1; DBMS_OUTPUT.PUT_LINE(a||'完成');     end loop; END;   |         0 |        56042 |
| D62BAB1A05D83614534EF5260991A487 | 2023-12-04 14:44:02.073641 | 172.16.100.137 |       0 |              | DECLARE    query_2 VARCHAR2(200) := 'SELECT * from OB_PLAN_TEST1 where DDID = :x';    a number :=1;   BEGIN     while a=1 LOOP execute immediate query_2 USING  '370623.122717135116785630990292275519114'; a:=a+1; DBMS_OUTPUT.PUT_LINE(a||'完成');     end loop; END;   |         0 |        51807 |
+----------------------------------+----------------------------+----------------+---------+--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------+--------------+
2 rows in set (0.01 sec)obclient [ACCOUNT]> select  * from  gv$ob_plan_cache_plan_stat where query_id ='D62BAB1A05D83614534EF5260991A487';
Empty set (0.057 sec)

单表的执行计划突变及验证过程:

一般单表计划改变,都是因为plan_cache被刷掉后,sql重新解析,因为各种原因(如统计信息失效或者对于这条sql代价比较低)生成了差的执行计划,后续sql会复用该计划导致负载异常。ps:ob每晚会定时合并,会收集存储引擎级别的统计信息,如果手工收集了统计信息,优先级会高于自动收集的统计信息。

--生成测试数据
CREATE TABLE "OB_PLAN_TEST1" ("DDID" VARCHAR2(40)  NOT NULL ENABLE,"DDNAME" VARCHAR2(128),"CCCID" VARCHAR2(32)  NOT NULL ENABLE,"FFFF" NUMBER(3),"DDDDD" NUMBER(1),"STATUSDATE" DATE,"FS" VARCHAR2(1024));declare
jid number :=0;
begin
loop  jid := jid+1;insert into OB_PLAN_TEST1 values( dbms_random.value(1,500000),'cd','DD'||jid,2,1,sysdate,'sdas');--commit;if  jid >2000000 thencommit;exit;end if;end loop;
end;
/commit;call dbms_stats.gather_table_stats('ACCOUNT','OB_PLAN_TEST1',granularity=>'ALL',method_opt=>'FOR ALL COLUMNS SIZE 128');create index idx_OB_PLAN_TEST1 on OB_PLAN_TEST1(DDID);update OB_PLAN_TEST1 set DDID=1 where rownum < 500000;
commit;--数据库版本(经测试在4.2.1版本仍然存在该问题)
observer (OceanBase 3.2.3.3)REVISION: 109010012023072721-72e06032a278e9939718a67c2512da1e9f94775a
BUILD_BRANCH: HEAD
BUILD_TIME: Jul 27 2023 22:10:46
BUILD_FLAGS: RelWithDebInfo
BUILD_INFO: Copyright (c) 2011-2020 Alipay Inc.
--验证过程
obclient> select  *  from OB_PLAN_TEST1 where DDID<> 1 and rownum=1;
+------------------------------------------+--------+---------+------+-------+---------------------+------+
| DDID                                     | DDNAME | CCCID   | FFFF | DDDDD | STATUSDATE          | FS   |
+------------------------------------------+--------+---------+------+-------+---------------------+------+
| 153477.033350996877667355771590526403007 | cd     | DD50000 |    2 |     1 | 2023-11-29 17:15:28 | sdas |
+------------------------------------------+--------+---------+------+-------+---------------------+------+
1 row in set (0.06 sec)
select count(*) from OB_PLAN_TEST1 ;
select count(*) from OB_PLAN_TEST1 where DDID='1';
select count(*) from OB_PLAN_TEST1 where DDID='153477.033350996877667355771590526403007';
explain select * from OB_PLAN_TEST1 where DDID='1'\G
explain select * from OB_PLAN_TEST1 where DDID='153477.033350996877667355771590526403007'\Gobclient> select count(*) from OB_PLAN_TEST1 ;
+----------+
| COUNT(*) |
+----------+
|   200001 |
+----------+
1 row in set (0.11 sec)
--DDID='1'为大账号
obclient> select count(*) from OB_PLAN_TEST1 where DDID='1';
+----------+
| COUNT(*) |
+----------+
|    49999 |
+----------+
1 row in set (0.04 sec)
--DDID='153477.033350996877667355771590526403007'为小账号
obclient> select count(*) from OB_PLAN_TEST1 where DDID='153477.033350996877667355771590526403007';
+----------+
| COUNT(*) |
+----------+
|        1 |
+----------+
1 row in set (0.00 sec)--可以看到explain执行计划是对的,大账号走全表扫描,小账号走索引扫描
obclient> explain select * from OB_PLAN_TEST1 where DDID='1'\G
*************************** 1. row ***************************
Query Plan: =============================================
|ID|OPERATOR  |NAME         |EST. ROWS|COST |
---------------------------------------------
|0 |TABLE SCAN|OB_PLAN_TEST1|59629    |78575|
=============================================Outputs & filters: 
-------------------------------------0 - output([OB_PLAN_TEST1.DDID], [OB_PLAN_TEST1.DDNAME], [OB_PLAN_TEST1.CCCID], [OB_PLAN_TEST1.FFFF], [OB_PLAN_TEST1.DDDDD], [OB_PLAN_TEST1.STATUSDATE], [OB_PLAN_TEST1.FS]), filter([OB_PLAN_TEST1.DDID = ?]), access([OB_PLAN_TEST1.DDID], [OB_PLAN_TEST1.DDNAME], [OB_PLAN_TEST1.CCCID], [OB_PLAN_TEST1.FFFF], [OB_PLAN_TEST1.DDDDD], [OB_PLAN_TEST1.STATUSDATE], [OB_PLAN_TEST1.FS]), partitions(p0)1 row in set (0.01 sec)obclient> explain select * from OB_PLAN_TEST1 where DDID='153477.033350996877667355771590526403007'\G
*************************** 1. row ***************************
Query Plan: ===============================================================
|ID|OPERATOR  |NAME                            |EST. ROWS|COST|
---------------------------------------------------------------
|0 |TABLE SCAN|OB_PLAN_TEST1(IDX_OB_PLAN_TEST1)|1        |4   |
===============================================================Outputs & filters: 
-------------------------------------0 - output([OB_PLAN_TEST1.DDID], [OB_PLAN_TEST1.DDNAME], [OB_PLAN_TEST1.CCCID], [OB_PLAN_TEST1.FFFF], [OB_PLAN_TEST1.DDDDD], [OB_PLAN_TEST1.STATUSDATE], [OB_PLAN_TEST1.FS]), filter(nil), access([OB_PLAN_TEST1.DDID], [OB_PLAN_TEST1.DDNAME], [OB_PLAN_TEST1.CCCID], [OB_PLAN_TEST1.FFFF], [OB_PLAN_TEST1.DDDDD], [OB_PLAN_TEST1.STATUSDATE], [OB_PLAN_TEST1.FS]), partitions(p0)1 row in set (0.00 sec)--清空plancache和sqlaudit,使接下来sql重新解析,方便查看
MySQL [oceanbase]> alter system flush plan cache global;
Query OK, 0 rows affected (0.10 sec)MySQL [oceanbase]> alter system flush sql audit global;
Query OK, 0 rows affected (0.20 sec)--分别执行大小账号的查询
obclient> select * from OB_PLAN_TEST1 where DDID='1';
.
.
49999 rows in set (0.29 sec)obclient> select * from OB_PLAN_TEST1 where DDID='153477.033350996877667355771590526403007';
+------------------------------------------+--------+---------+------+-------+---------------------+------+
| DDID                                     | DDNAME | CCCID   | FFFF | DDDDD | STATUSDATE          | FS   |
+------------------------------------------+--------+---------+------+-------+---------------------+------+
| 153477.033350996877667355771590526403007 | cd     | DD50000 |    2 |     1 | 2023-11-29 17:15:28 | sdas |
+------------------------------------------+--------+---------+------+-------+---------------------+------+
1 row in set (0.14 sec)MySQL [oceanbase]> select  sql_id,query_sql from  gv$sql_audit  where query_sql like '%select * from OB_PLAN_TEST1 where DDID%' and  query_sql not like '%query_sql%' and query_sql not like '%explain%'\G
*************************** 1. row ***************************sql_id: CBD4BDA406ED0B73D47864A5739C44CE
query_sql: select * from OB_PLAN_TEST1 where DDID='1'
*************************** 2. row ***************************sql_id: CBD4BDA406ED0B73D47864A5739C44CE
query_sql: select * from OB_PLAN_TEST1 where DDID='153477.033350996877667355771590526403007'
2 rows in set (2.61 sec)MySQL [oceanbase]> select /*+parallel(32)*/ sql_id,usec_to_time(request_time),svr_ip,plan_id,params_value,query_sql,plan_type from gv$sql_audit where sql_id='CBD4BDA406ED0B73D47864A5739C44CE' order by request_time limit 10;
+----------------------------------+----------------------------+-------------+---------+--------------+-----------------------------------------------------------------------------------+-----------+
| sql_id                           | usec_to_time(request_time) | svr_ip      | plan_id | params_value | query_sql                                                                         | plan_type |
+----------------------------------+----------------------------+-------------+---------+--------------+-----------------------------------------------------------------------------------+-----------+
| CBD4BDA406ED0B73D47864A5739C44CE | 2023-11-29 17:22:01.244336 | 111.11.11.1 | 3081629 |              | select * from OB_PLAN_TEST1 where DDID='1'                                        |         1 |
| CBD4BDA406ED0B73D47864A5739C44CE | 2023-11-29 17:22:28.842721 | 111.11.11.1 | 3081629 |              | select * from OB_PLAN_TEST1 where DDID='153477.033350996877667355771590526403007' |         1 |
+----------------------------------+----------------------------+-------------+---------+--------------+-----------------------------------------------------------------------------------+-----------+
2 rows in set (0.87 sec)
--可以看到最终小账号也复用了全表扫描的执行计划
MySQL [oceanbase]> select plan_id, operator, name, rows, cost from gv$plan_cache_plan_explain where tenant_id=1005 and ip='111.11.11.1' and port=2882 and plan_id=3081629;
+---------+----------------+---------------+-------+-------+
| plan_id | operator       | name          | rows  | cost  |
+---------+----------------+---------------+-------+-------+
| 3081629 | PHY_TABLE_SCAN | OB_PLAN_TEST1 | 59629 | 78574 |
+---------+----------------+---------------+-------+-------+
1 row in set (0.00 sec)

该问题其实可以使用ACS解决,但是ob的acs在实验室测试阶段引入了很多问题,现在还没有上线

分区表的执行计划突变及验证过程:

分区表相关的计划突变其实与单表类似,但是后来ob对这块做了相关优化,所以我们单独做个测试。

--生成测试数据
CREATE TABLE "OB_PLAN_TEST1" ("DDID" VARCHAR2(40)  NOT NULL ENABLE,"DDNAME" VARCHAR2(128),"CCCID" VARCHAR2(32)  NOT NULL ENABLE,"FFFF" NUMBER(3),"DDDDD" NUMBER(1),"STATUSDATE" DATE,"FS" VARCHAR2(1024),CITY NUMBER(5) NOT NULL ENABLE)partition by range("CITY")
(partition P_100 values less than (200),
partition P_200 values less than (300),
partition P_300 values less than (400),
partition P_400 values less than (500));declare
jid number :=0;
begin
loop  jid := jid+1;insert into OB_PLAN_TEST1 values( dbms_random.value(1,500000),'cd','DD'||jid,2,1,sysdate,'sdas',400);--commit;if  jid >200000 thencommit;exit;end if;end loop;
end;
/
insert into OB_PLAN_TEST1 values( dbms_random.value(1,500000),'cd','DD'||'www',2,1,sysdate,'sdas',300);
commit;select  CITY,count(*) from  OB_PLAN_TEST1 group by CITY;
create index idx_OB_PLAN_TEST1 on OB_PLAN_TEST1(DDID) local;
call dbms_stats.gather_table_stats('ACCOUNT','OB_PLAN_TEST1',granularity=>'ALL',method_opt=>'FOR ALL COLUMNS SIZE 128');--3.2.3的前期版本
observer (OceanBase 3.2.3.3)REVISION: 109010012023072721-72e06032a278e9939718a67c2512da1e9f94775a
BUILD_BRANCH: HEAD
BUILD_TIME: Jul 27 2023 22:10:46
BUILD_FLAGS: RelWithDebInfo
BUILD_INFO: Copyright (c) 2011-2020 Alipay Inc.--测试过程,分区300为小分区,分区400为大分区obclient> select  CITY,count(*) from  OB_PLAN_TEST1 group by CITY;
+------+----------+
| CITY | COUNT(*) |
+------+----------+
|  300 |        1 |
|  400 |   200001 |
+------+----------+
2 rows in set (0.20 sec)
obclient> select  *  from OB_PLAN_TEST1 where CITY=300;
+------------------------------------------+--------+-------+------+-------+---------------------+------+------+
| DDID                                     | DDNAME | CCCID | FFFF | DDDDD | STATUSDATE          | FS   | CITY |
+------------------------------------------+--------+-------+------+-------+---------------------+------+------+
| 438916.090508550075909523829593371519369 | cd     | DDwww |    2 |     1 | 2023-12-01 16:41:23 | sdas |  300 |
+------------------------------------------+--------+-------+------+-------+---------------------+------+------+
1 row in set (0.03 sec)obclient> select  *  from OB_PLAN_TEST1 where CITY=400 and rownum=1;
+------------------------------------------+--------+-------+------+-------+---------------------+------+------+
| DDID                                     | DDNAME | CCCID | FFFF | DDDDD | STATUSDATE          | FS   | CITY |
+------------------------------------------+--------+-------+------+-------+---------------------+------+------+
| 226565.232611556997487602769478763788588 | cd     | DD1   |    2 |     1 | 2023-12-01 16:38:54 | sdas |  400 |
+------------------------------------------+--------+-------+------+-------+---------------------+------+------+
1 row in set (0.02 sec)explain select * from OB_PLAN_TEST1 where DDID='438916.090508550075909523829593371519369' and  CITY=300\G
explain select * from OB_PLAN_TEST1 where DDID='226565.232611556997487602769478763788588' and  CITY=400\G--可以看到explain执行计划是对的,小分区走全表扫描,大分区走索引扫描
obclient> explain select * from OB_PLAN_TEST1 where DDID='438916.090508550075909523829593371519369' and  CITY=300\G
*************************** 1. row ***************************
Query Plan: ============================================
|ID|OPERATOR  |NAME         |EST. ROWS|COST|
--------------------------------------------
|0 |TABLE SCAN|OB_PLAN_TEST1|1        |1   |
============================================Outputs & filters: 
-------------------------------------0 - output([OB_PLAN_TEST1.DDID], [OB_PLAN_TEST1.DDNAME], [OB_PLAN_TEST1.CCCID], [OB_PLAN_TEST1.FFFF], [OB_PLAN_TEST1.DDDDD], [OB_PLAN_TEST1.STATUSDATE], [OB_PLAN_TEST1.FS], [OB_PLAN_TEST1.CITY]), filter([OB_PLAN_TEST1.DDID = ?]), access([OB_PLAN_TEST1.CITY], [OB_PLAN_TEST1.DDID], [OB_PLAN_TEST1.DDNAME], [OB_PLAN_TEST1.CCCID], [OB_PLAN_TEST1.FFFF], [OB_PLAN_TEST1.DDDDD], [OB_PLAN_TEST1.STATUSDATE], [OB_PLAN_TEST1.FS]), partitions(p2)1 row in set (0.00 sec)obclient> explain select * from OB_PLAN_TEST1 where DDID='226565.232611556997487602769478763788588' and  CITY=400\G
*************************** 1. row ***************************
Query Plan: ===============================================================
|ID|OPERATOR  |NAME                            |EST. ROWS|COST|
---------------------------------------------------------------
|0 |TABLE SCAN|OB_PLAN_TEST1(IDX_OB_PLAN_TEST1)|1        |4   |
===============================================================Outputs & filters: 
-------------------------------------0 - output([OB_PLAN_TEST1.DDID], [OB_PLAN_TEST1.DDNAME], [OB_PLAN_TEST1.CCCID], [OB_PLAN_TEST1.FFFF], [OB_PLAN_TEST1.DDDDD], [OB_PLAN_TEST1.STATUSDATE], [OB_PLAN_TEST1.FS], [OB_PLAN_TEST1.CITY]), filter(nil), access([OB_PLAN_TEST1.CITY], [OB_PLAN_TEST1.DDID], [OB_PLAN_TEST1.DDNAME], [OB_PLAN_TEST1.CCCID], [OB_PLAN_TEST1.FFFF], [OB_PLAN_TEST1.DDDDD], [OB_PLAN_TEST1.STATUSDATE], [OB_PLAN_TEST1.FS]), partitions(p3)1 row in set (0.00 sec)--清空plancache和sqlaudit
alter system flush plan cache global;
alter system flush sql audit global;MySQL [oceanbase]> select  sql_id,query_sql from  gv$sql_audit  where query_sql like '%select * from OB_PLAN_TEST1 where DDID=%' and  query_sql not like '%query_sql%' and query_sql not like '%explain%'\G
*************************** 1. row ***************************sql_id: 2FA089055677A69C67B9E4F816A8D9EF
query_sql: select * from OB_PLAN_TEST1 where DDID='438916.090508550075909523829593371519369' and  CITY=300
*************************** 2. row ***************************sql_id: 2FA089055677A69C67B9E4F816A8D9EF
query_sql: select * from OB_PLAN_TEST1 where DDID='226565.232611556997487602769478763788588' and  CITY=400
2 rows in set (0.17 sec)MySQL [oceanbase]> select /*+parallel(32)*/ sql_id,usec_to_time(request_time),svr_ip,plan_id,params_value,query_sql,plan_type,ELAPSED_TIME from gv$sql_audit where sql_id='2FA089055677A69C67B9E4F816A8D9EF' order by request_time limit 50;
+----------------------------------+----------------------------+-------------+---------+--------------+-------------------------------------------------------------------------------------------------+-----------+--------------+
| sql_id                           | usec_to_time(request_time) | svr_ip      | plan_id | params_value | query_sql                                                                                       | plan_type | ELAPSED_TIME |
+----------------------------------+----------------------------+-------------+---------+--------------+-------------------------------------------------------------------------------------------------+-----------+--------------+
| 2FA089055677A69C67B9E4F816A8D9EF | 2023-12-01 16:48:50.012069 | 134.84.16.2 |    7364 |              | select * from OB_PLAN_TEST1 where DDID='438916.090508550075909523829593371519369' and  CITY=300 |         1 |         1706 |
| 2FA089055677A69C67B9E4F816A8D9EF | 2023-12-01 16:48:59.847533 | 134.84.16.2 |    7364 |              | select * from OB_PLAN_TEST1 where DDID='226565.232611556997487602769478763788588' and  CITY=400 |         1 |       144013 |
+----------------------------------+----------------------------+-------------+---------+--------------+-------------------------------------------------------------------------------------------------+-----------+--------------+
2 rows in set (0.07 sec)
--可以看到大分区账号复用了小分区账号的执行计划,走了错误的执行计划
MySQL [oceanbase]> select plan_id, operator, name, rows, cost from gv$plan_cache_plan_explain where tenant_id=1005 and ip='134.84.16.2' and port=2882 and plan_id=7364;
+---------+----------------+---------------+------+------+
| plan_id | operator       | name          | rows | cost |
+---------+----------------+---------------+------+------+
|    7364 | PHY_TABLE_SCAN | OB_PLAN_TEST1 |    1 |    0 |
+---------+----------------+---------------+------+------+
1 row in set (0.01 sec)--3.2.3后期版本引入了两个参数
observer (OceanBase 3.2.3.3)REVISION: 110020012023110315-55cf8deebb891498d8c87ab742cde4809c018219
BUILD_BRANCH: HEAD
BUILD_TIME: Nov  3 2023 15:27:14
BUILD_FLAGS: RelWithDebInfo
BUILD_INFO: Copyright (c) 2011-2020 Alipay Inc.<><><><><><><>
##############################
--根据分区分裂执行计划
MySQL [oceanbase]> alter system set _enable_partition_level_acs = True tenant='cc1cs';
Query OK, 0 rows affected (0.03 sec)
--索引代价评估(该参数在这个实验中先不介绍了)
MySQL [oceanbase]>  alter system set optimizer_index_cost_adj =1 tenant='cc1cs';
Query OK, 0 rows affected (0.02 sec)MySQL [oceanbase]> select  * from __all_virtual_tenant_parameter_info  where name like '%enable_partition_level_acs%';
+-----------+-------+----------+-------------+----------+-----------------------------+-----------+-------+-------------------------------+---------+--------+---------+-------------------+
| tenant_id | zone  | svr_type | svr_ip      | svr_port | name                        | data_type | value | info                          | section | scope  | source  | edit_level        |
+-----------+-------+----------+-------------+----------+-----------------------------+-----------+-------+-------------------------------+---------+--------+---------+-------------------+
|         1 | zone1 | observer | 122.22.22.8 |     2882 | _enable_partition_level_acs | NULL      | True  | enable acs in partition level | TENANT  | TENANT | DEFAULT | DYNAMIC_EFFECTIVE |
|      1003 | zone1 | observer | 122.22.22.9 |     2882 | _enable_partition_level_acs | NULL      | True  | enable acs in partition level | TENANT  | TENANT | DEFAULT | DYNAMIC_EFFECTIVE |
|         1 | zone1 | observer | 122.22.22.8 |     2882 | _enable_partition_level_acs | NULL      | True  | enable acs in partition level | TENANT  | TENANT | DEFAULT | DYNAMIC_EFFECTIVE |
|      1003 | zone1 | observer | 122.22.22.8 |     2882 | _enable_partition_level_acs | NULL      | True  | enable acs in partition level | TENANT  | TENANT | DEFAULT | DYNAMIC_EFFECTIVE |
+-----------+-------+----------+-------------+----------+-----------------------------+-----------+-------+-------------------------------+---------+--------+---------+-------------------+
4 rows in set (0.06 sec)
MySQL [oceanbase]> select  * from __all_virtual_tenant_parameter_info  where name like '%optimizer_index_cost_adj%';
+-----------+-------+----------+-------------+----------+--------------------------+-----------+-------+------------------------------+---------+--------+---------+-------------------+
| tenant_id | zone  | svr_type | svr_ip      | svr_port | name                     | data_type | value | info                         | section | scope  | source  | edit_level        |
+-----------+-------+----------+-------------+----------+--------------------------+-----------+-------+------------------------------+---------+--------+---------+-------------------+
|         1 | zone1 | observer | 122.22.22.8 |     2882 | optimizer_index_cost_adj | NULL      | 0     | adjust costing of index scan | TENANT  | TENANT | DEFAULT | DYNAMIC_EFFECTIVE |
|      1003 | zone1 | observer | 122.22.22.8 |     2882 | optimizer_index_cost_adj | NULL      | 1     | adjust costing of index scan | TENANT  | TENANT | DEFAULT | DYNAMIC_EFFECTIVE |
|         1 | zone1 | observer | 122.22.22.9 |     2882 | optimizer_index_cost_adj | NULL      | 0     | adjust costing of index scan | TENANT  | TENANT | DEFAULT | DYNAMIC_EFFECTIVE |
|      1003 | zone1 | observer | 122.22.22.9 |     2882 | optimizer_index_cost_adj | NULL      | 1     | adjust costing of index scan | TENANT  | TENANT | DEFAULT | DYNAMIC_EFFECTIVE |
+-----------+-------+----------+-------------+----------+--------------------------+-----------+-------+------------------------------+---------+--------+---------+-------------------+
4 rows in set (0.06 sec)##########################
--验证过程与上面一致
obclient> select  CITY,count(*) from  OB_PLAN_TEST1 group by CITY;
+------+----------+
| CITY | COUNT(*) |
+------+----------+
|  300 |        1 |
|  400 |   200001 |
+------+----------+
2 rows in set (0.20 sec)obclient> select  *  from OB_PLAN_TEST1 where CITY=300;
+------------------------------------------+--------+-------+------+-------+---------------------+------+------+
| DDID                                     | DDNAME | CCCID | FFFF | DDDDD | STATUSDATE          | FS   | CITY |
+------------------------------------------+--------+-------+------+-------+---------------------+------+------+
| 344423.097813308868309580547313255124084 | cd     | DDwww |    2 |     1 | 2023-12-01 16:52:32 | sdas |  300 |
+------------------------------------------+--------+-------+------+-------+---------------------+------+------+
1 row in set (0.04 sec)obclient> select  *  from OB_PLAN_TEST1 where CITY=400 and rownum=1;
+------------------------------------------+--------+-------+------+-------+---------------------+------+------+
| DDID                                     | DDNAME | CCCID | FFFF | DDDDD | STATUSDATE          | FS   | CITY |
+------------------------------------------+--------+-------+------+-------+---------------------+------+------+
| 119548.132022013705188211994065427849317 | cd     | DD1   |    2 |     1 | 2023-12-01 16:39:50 | sdas |  400 |
+------------------------------------------+--------+-------+------+-------+---------------------+------+------+
1 row in set (0.06 sec)explain select * from OB_PLAN_TEST1 where DDID='344423.097813308868309580547313255124084' and  CITY=300\G
explain select * from OB_PLAN_TEST1 where DDID='119548.132022013705188211994065427849317' and  CITY=400\Gobclient> explain select * from OB_PLAN_TEST1 where DDID='344423.097813308868309580547313255124084' and  CITY=300\G
*************************** 1. row ***************************
Query Plan: ============================================
|ID|OPERATOR  |NAME         |EST. ROWS|COST|
--------------------------------------------
|0 |TABLE SCAN|OB_PLAN_TEST1|1        |1   |
============================================Outputs & filters: 
-------------------------------------0 - output([OB_PLAN_TEST1.DDID], [OB_PLAN_TEST1.DDNAME], [OB_PLAN_TEST1.CCCID], [OB_PLAN_TEST1.FFFF], [OB_PLAN_TEST1.DDDDD], [OB_PLAN_TEST1.STATUSDATE], [OB_PLAN_TEST1.FS], [OB_PLAN_TEST1.CITY]), filter([OB_PLAN_TEST1.DDID = ?]), access([OB_PLAN_TEST1.CITY], [OB_PLAN_TEST1.DDID], [OB_PLAN_TEST1.DDNAME], [OB_PLAN_TEST1.CCCID], [OB_PLAN_TEST1.FFFF], [OB_PLAN_TEST1.DDDDD], [OB_PLAN_TEST1.STATUSDATE], [OB_PLAN_TEST1.FS]), partitions(p2)1 row in set (0.01 sec)obclient> explain select * from OB_PLAN_TEST1 where DDID='119548.132022013705188211994065427849317' and  CITY=400\G
*************************** 1. row ***************************
Query Plan: =========================================================================
|ID|OPERATOR            |NAME                            |EST. ROWS|COST|
-------------------------------------------------------------------------
|0 |EXCHANGE IN REMOTE  |                                |1        |6   |
|1 | EXCHANGE OUT REMOTE|                                |1        |4   |
|2 |  TABLE SCAN        |OB_PLAN_TEST1(IDX_OB_PLAN_TEST1)|1        |4   |
=========================================================================Outputs & filters: 
-------------------------------------0 - output([OB_PLAN_TEST1.DDID], [OB_PLAN_TEST1.DDNAME], [OB_PLAN_TEST1.CCCID], [OB_PLAN_TEST1.FFFF], [OB_PLAN_TEST1.DDDDD], [OB_PLAN_TEST1.STATUSDATE], [OB_PLAN_TEST1.FS], [OB_PLAN_TEST1.CITY]), filter(nil)1 - output([OB_PLAN_TEST1.DDID], [OB_PLAN_TEST1.DDNAME], [OB_PLAN_TEST1.CCCID], [OB_PLAN_TEST1.FFFF], [OB_PLAN_TEST1.DDDDD], [OB_PLAN_TEST1.STATUSDATE], [OB_PLAN_TEST1.FS], [OB_PLAN_TEST1.CITY]), filter(nil)2 - output([OB_PLAN_TEST1.CITY], [OB_PLAN_TEST1.DDID], [OB_PLAN_TEST1.DDNAME], [OB_PLAN_TEST1.CCCID], [OB_PLAN_TEST1.FFFF], [OB_PLAN_TEST1.DDDDD], [OB_PLAN_TEST1.STATUSDATE], [OB_PLAN_TEST1.FS]), filter(nil), access([OB_PLAN_TEST1.CITY], [OB_PLAN_TEST1.DDID], [OB_PLAN_TEST1.DDNAME], [OB_PLAN_TEST1.CCCID], [OB_PLAN_TEST1.FFFF], [OB_PLAN_TEST1.DDDDD], [OB_PLAN_TEST1.STATUSDATE], [OB_PLAN_TEST1.FS]), partitions(p3)1 row in set (0.01 sec)MySQL [oceanbase]> select  sql_id,query_sql from  gv$sql_audit  where query_sql like '%select * from OB_PLAN_TEST1 where DDID=%' and  query_sql not like '%query_sql%' and query_sql not like '%explain%'\G
*************************** 1. row ***************************sql_id: 2FA089055677A69C67B9E4F816A8D9EF
query_sql: select * from OB_PLAN_TEST1 where DDID='344423.097813308868309580547313255124084' and  CITY=300
*************************** 2. row ***************************sql_id: 2FA089055677A69C67B9E4F816A8D9EF
query_sql: select * from OB_PLAN_TEST1 where DDID='119548.132022013705188211994065427849317' and  CITY=400
2 rows in set (0.04 sec)MySQL [oceanbase]> select /*+parallel(32)*/ sql_id,usec_to_time(request_time),svr_ip,plan_id,params_value,query_sql,plan_type,ELAPSED_TIME from gv$sql_audit where sql_id='2FA089055677A69C67B9E4F816A8D9EF' order by request_time limit 50;
+----------------------------------+----------------------------+-------------+---------+--------------+-------------------------------------------------------------------------------------------------+-----------+--------------+
| sql_id                           | usec_to_time(request_time) | svr_ip      | plan_id | params_value | query_sql                                                                                       | plan_type | ELAPSED_TIME |
+----------------------------------+----------------------------+-------------+---------+--------------+-------------------------------------------------------------------------------------------------+-----------+--------------+
| 2FA089055677A69C67B9E4F816A8D9EF | 2023-12-01 16:55:27.879506 | 122.22.22.9 |  110392 |              | select * from OB_PLAN_TEST1 where DDID='344423.097813308868309580547313255124084' and  CITY=300 |         1 |         2915 |
| 2FA089055677A69C67B9E4F816A8D9EF | 2023-12-01 16:55:38.931865 | 122.22.22.9 |  110398 |              | select * from OB_PLAN_TEST1 where DDID='119548.132022013705188211994065427849317' and  CITY=400 |         2 |         9502 |
+----------------------------------+----------------------------+-------------+---------+--------------+-------------------------------------------------------------------------------------------------+-----------+--------------+
2 rows in set (0.05 sec)--可以看到开启分区分裂计划的参数后生成了两个计划,两个sql都走了正确的计划
MySQL [oceanbase]> select plan_id, operator, name, rows, cost from gv$plan_cache_plan_explain where tenant_id=1003 and ip='122.22.22.9' and port=2882 and plan_id=110392;
+---------+----------------+---------------+------+------+
| plan_id | operator       | name          | rows | cost |
+---------+----------------+---------------+------+------+
|  110392 | PHY_TABLE_SCAN | OB_PLAN_TEST1 |    1 |    0 |
+---------+----------------+---------------+------+------+
1 row in set (0.01 sec)MySQL [oceanbase]> select plan_id, operator, name, rows, cost from gv$plan_cache_plan_explain where tenant_id=1003 and ip='122.22.22.9' and port=2882 and plan_id=110398;
+---------+----------------------+----------------------------------+------+------+
| plan_id | operator             | name                             | rows | cost |
+---------+----------------------+----------------------------------+------+------+
|  110398 | PHY_DIRECT_RECEIVE   | NULL                             |    1 |    5 |
|  110398 |  PHY_DIRECT_TRANSMIT | NULL                             |    1 |    3 |
|  110398 |   PHY_TABLE_SCAN     | OB_PLAN_TEST1(IDX_OB_PLAN_TEST1) |    1 |    3 |
+---------+----------------------+----------------------------------+------+------+
3 rows in set (0.00 sec)

因为我在4.2.1版本上没有找到该参数,那验证下实际表现如何

--版本信息
observer (OceanBase 4.2.1.1)REVISION: 101010022023110921-5d0b2ec58d7661e382f65d3753b65f3a914f89ec
BUILD_BRANCH: HEAD
BUILD_TIME: Nov  9 2023 21:27:01
BUILD_FLAGS: RelWithDebInfo
BUILD_INFO: Copyright (c) 2011-present OceanBase Inc.--数据分布,与上面实验一样,大小分区
obclient [ACCOUNT]> select  CITY,count(*) from  OB_PLAN_TEST1 group by CITY;
+------+----------+
| CITY | COUNT(*) |
+------+----------+
|  300 |        1 |
|  400 |   200001 |
+------+----------+
2 rows in set (0.305 sec)
obclient [ACCOUNT]> select  *  from OB_PLAN_TEST1 where CITY=300;
+------------------------------------------+--------+-------+------+-------+------------+------+------+
| DDID                                     | DDNAME | CCCID | FFFF | DDDDD | STATUSDATE | FS   | CITY |
+------------------------------------------+--------+-------+------+-------+------------+------+------+
| 298225.370594538611501792855979394021071 | cd     | DDwww |    2 |     1 | 01-DEC-23  | sdas |  300 |
+------------------------------------------+--------+-------+------+-------+------------+------+------+
1 row in set (0.083 sec)obclient [ACCOUNT]> select  *  from OB_PLAN_TEST1 where CITY=400 and rownum=1;
+------------------------------------------+--------+-------+------+-------+------------+------+------+
| DDID                                     | DDNAME | CCCID | FFFF | DDDDD | STATUSDATE | FS   | CITY |
+------------------------------------------+--------+-------+------+-------+------------+------+------+
| 269826.523111291697766623468575040129842 | cd     | DD1   |    2 |     1 | 01-DEC-23  | sdas |  400 |
+------------------------------------------+--------+-------+------+-------+------------+------+------+
1 row in set (0.017 sec)explain select * from OB_PLAN_TEST1 where DDID='298225.370594538611501792855979394021071' and  CITY=300;
explain select * from OB_PLAN_TEST1 where DDID='269826.523111291697766623468575040129842' and  CITY=400;--这里不同的是,小分区也走了索引,因为代价不大,所以这个计划没有问题
obclient [ACCOUNT]> explain select * from OB_PLAN_TEST1 where DDID='298225.370594538611501792855979394021071' and  CITY=300;
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Query Plan                                                                                                                                                            |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ============================================================================                                                                                          |
| |ID|OPERATOR        |NAME                            |EST.ROWS|EST.TIME(us)|                                                                                          |
| ----------------------------------------------------------------------------                                                                                          |
| |0 |TABLE RANGE SCAN|OB_PLAN_TEST1(IDX_OB_PLAN_TEST1)|1       |7           |                                                                                          |
| ============================================================================                                                                                          |
| Outputs & filters:                                                                                                                                                    |
| -------------------------------------                                                                                                                                 |
|   0 - output([OB_PLAN_TEST1.DDID], [OB_PLAN_TEST1.DDNAME], [OB_PLAN_TEST1.CCCID], [OB_PLAN_TEST1.FFFF], [OB_PLAN_TEST1.DDDDD], [OB_PLAN_TEST1.STATUSDATE],            |
|        [OB_PLAN_TEST1.FS], [OB_PLAN_TEST1.CITY]), filter([OB_PLAN_TEST1.CITY = 300]), rowset=16                                                                       |
|       access([OB_PLAN_TEST1.__pk_increment], [OB_PLAN_TEST1.CITY], [OB_PLAN_TEST1.DDID], [OB_PLAN_TEST1.DDNAME], [OB_PLAN_TEST1.CCCID], [OB_PLAN_TEST1.FFFF],         |
|        [OB_PLAN_TEST1.DDDDD], [OB_PLAN_TEST1.STATUSDATE], [OB_PLAN_TEST1.FS]), partitions(p2)                                                                         |
|       is_index_back=true, is_global_index=false, filter_before_indexback[false],                                                                                      |
|       range_key([OB_PLAN_TEST1.DDID], [OB_PLAN_TEST1.__pk_increment]), range(298225.370594538611501792855979394021071,MIN ; 298225.370594538611501792855979394021071, |
|       MAX),                                                                                                                                                           |
|       range_cond([OB_PLAN_TEST1.DDID = cast('298225.370594538611501792855979394021071', VARCHAR2(1048576 ))])                                                         |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
15 rows in set (0.004 sec)obclient [ACCOUNT]> explain select * from OB_PLAN_TEST1 where DDID='269826.523111291697766623468575040129842' and  CITY=400;
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Query Plan                                                                                                                                                            |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ============================================================================                                                                                          |
| |ID|OPERATOR        |NAME                            |EST.ROWS|EST.TIME(us)|                                                                                          |
| ----------------------------------------------------------------------------                                                                                          |
| |0 |TABLE RANGE SCAN|OB_PLAN_TEST1(IDX_OB_PLAN_TEST1)|1       |7           |                                                                                          |
| ============================================================================                                                                                          |
| Outputs & filters:                                                                                                                                                    |
| -------------------------------------                                                                                                                                 |
|   0 - output([OB_PLAN_TEST1.DDID], [OB_PLAN_TEST1.DDNAME], [OB_PLAN_TEST1.CCCID], [OB_PLAN_TEST1.FFFF], [OB_PLAN_TEST1.DDDDD], [OB_PLAN_TEST1.STATUSDATE],            |
|        [OB_PLAN_TEST1.FS], [OB_PLAN_TEST1.CITY]), filter([OB_PLAN_TEST1.CITY = 400]), rowset=16                                                                       |
|       access([OB_PLAN_TEST1.__pk_increment], [OB_PLAN_TEST1.CITY], [OB_PLAN_TEST1.DDID], [OB_PLAN_TEST1.DDNAME], [OB_PLAN_TEST1.CCCID], [OB_PLAN_TEST1.FFFF],         |
|        [OB_PLAN_TEST1.DDDDD], [OB_PLAN_TEST1.STATUSDATE], [OB_PLAN_TEST1.FS]), partitions(p3)                                                                         |
|       is_index_back=true, is_global_index=false, filter_before_indexback[false],                                                                                      |
|       range_key([OB_PLAN_TEST1.DDID], [OB_PLAN_TEST1.__pk_increment]), range(269826.523111291697766623468575040129842,MIN ; 269826.523111291697766623468575040129842, |
|       MAX),                                                                                                                                                           |
|       range_cond([OB_PLAN_TEST1.DDID = cast('269826.523111291697766623468575040129842', VARCHAR2(1048576 ))])                                                         |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
15 rows in set (0.017 sec)--这里我验证了个特殊sql,传参为空,我们很多场景遇到过传参为空导致计划突变引发的性能抖动
obclient [ACCOUNT]> explain select * from OB_PLAN_TEST1 where DDID='' and  CITY=200;
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Query Plan                                                                                                                                                                       |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ==================================================================                                                                                                               |
| |ID|OPERATOR                 |NAME         |EST.ROWS|EST.TIME(us)|                                                                                                               |
| ------------------------------------------------------------------                                                                                                               |
| |0 |PX COORDINATOR           |             |200002  |1140164     |                                                                                                               |
| |1 |└─EXCHANGE OUT DISTR     |:EX10000     |200002  |797399      |                                                                                                               |
| |2 |  └─PX PARTITION ITERATOR|             |200002  |26293       |                                                                                                               |
| |3 |    └─TABLE FULL SCAN    |OB_PLAN_TEST1|200002  |26293       |                                                                                                               |
| ==================================================================                                                                                                               |
| Outputs & filters:                                                                                                                                                               |
| -------------------------------------                                                                                                                                            |
|   0 - output([INTERNAL_FUNCTION(OB_PLAN_TEST1.DDID, OB_PLAN_TEST1.DDNAME, OB_PLAN_TEST1.CCCID, OB_PLAN_TEST1.FFFF, OB_PLAN_TEST1.DDDDD, OB_PLAN_TEST1.STATUSDATE,                |
|        OB_PLAN_TEST1.FS, OB_PLAN_TEST1.CITY)]), filter(nil), startup_filter([0]), rowset=256                                                                                     |
|   1 - output([INTERNAL_FUNCTION(OB_PLAN_TEST1.DDID, OB_PLAN_TEST1.DDNAME, OB_PLAN_TEST1.CCCID, OB_PLAN_TEST1.FFFF, OB_PLAN_TEST1.DDDDD, OB_PLAN_TEST1.STATUSDATE,                |
|        OB_PLAN_TEST1.FS, OB_PLAN_TEST1.CITY)]), filter(nil), rowset=256                                                                                                          |
|       dop=1                                                                                                                                                                      |
|   2 - output([OB_PLAN_TEST1.CITY], [OB_PLAN_TEST1.DDID], [OB_PLAN_TEST1.DDNAME], [OB_PLAN_TEST1.CCCID], [OB_PLAN_TEST1.FFFF], [OB_PLAN_TEST1.DDDDD], [OB_PLAN_TEST1.STATUSDATE], |
|        [OB_PLAN_TEST1.FS]), filter(nil), rowset=256                                                                                                                              |
|       force partition granule                                                                                                                                                    |
|   3 - output([OB_PLAN_TEST1.CITY], [OB_PLAN_TEST1.DDID], [OB_PLAN_TEST1.DDNAME], [OB_PLAN_TEST1.CCCID], [OB_PLAN_TEST1.FFFF], [OB_PLAN_TEST1.DDDDD], [OB_PLAN_TEST1.STATUSDATE], |
|        [OB_PLAN_TEST1.FS]), filter(nil), rowset=256                                                                                                                              |
|       access([OB_PLAN_TEST1.CITY], [OB_PLAN_TEST1.DDID], [OB_PLAN_TEST1.DDNAME], [OB_PLAN_TEST1.CCCID], [OB_PLAN_TEST1.FFFF], [OB_PLAN_TEST1.DDDDD], [OB_PLAN_TEST1.STATUSDATE], |
|        [OB_PLAN_TEST1.FS]), partitions(p[0-3])                                                                                                                                   |
|       is_index_back=false, is_global_index=false,                                                                                                                                |
|       range_key([OB_PLAN_TEST1.__pk_increment]), range(MIN ; MAX)always true                                                                                                     |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
24 rows in set (0.019 sec)alter system flush plan cache global;
alter system flush sql audit global;MySQL [oceanbase]> select  sql_id,query_sql from  gv$ob_sql_audit  where query_sql like '%select * from OB_PLAN_TEST1 where DDID=%' and  query_sql not like '%query_sql%' and query_sql not like '%explain%'\G
*************************** 1. row ***************************sql_id: 2FA089055677A69C67B9E4F816A8D9EF
query_sql: select * from OB_PLAN_TEST1 where DDID='' and  CITY=200
*************************** 2. row ***************************sql_id: 2FA089055677A69C67B9E4F816A8D9EF
query_sql: select * from OB_PLAN_TEST1 where DDID='298225.370594538611501792855979394021071' and  CITY=300
*************************** 3. row ***************************sql_id: 2FA089055677A69C67B9E4F816A8D9EF
query_sql: select * from OB_PLAN_TEST1 where DDID='269826.523111291697766623468575040129842' and  CITY=400
3 rows in set (0.03 sec)--可以看到生成的是同一个sqlid,生成的计划不同
MySQL [oceanbase]> select /*+parallel(32)*/ sql_id,usec_to_time(request_time),svr_ip,plan_id,params_value,query_sql,plan_type,ELAPSED_TIME from gv$ob_sql_audit where sql_id='2FA089055677A69C67B9E4F816A8D9EF' order by request_time limit 50;
+----------------------------------+----------------------------+----------------+---------+--------------+-------------------------------------------------------------------------------------------------+-----------+--------------+
| sql_id                           | usec_to_time(request_time) | svr_ip         | plan_id | params_value | query_sql                                                                                       | plan_type | ELAPSED_TIME |
+----------------------------------+----------------------------+----------------+---------+--------------+-------------------------------------------------------------------------------------------------+-----------+--------------+
| 2FA089055677A69C67B9E4F816A8D9EF | 2023-12-01 17:24:20.618319 | 172.16.100.137 |    2185 |              | select * from OB_PLAN_TEST1 where DDID='' and  CITY=200                                         |         3 |         5143 |
| 2FA089055677A69C67B9E4F816A8D9EF | 2023-12-01 17:24:33.558938 | 172.16.100.137 |    2188 |              | select * from OB_PLAN_TEST1 where DDID='298225.370594538611501792855979394021071' and  CITY=300 |         1 |         7472 |
| 2FA089055677A69C67B9E4F816A8D9EF | 2023-12-01 17:24:40.374061 | 172.16.100.137 |    2188 |              | select * from OB_PLAN_TEST1 where DDID='269826.523111291697766623468575040129842' and  CITY=400 |         1 |       167090 |
+----------------------------------+----------------------------+----------------+---------+--------------+-------------------------------------------------------------------------------------------------+-----------+--------------+
3 rows in set (0.02 sec)--检查可以发现计划是对的,后来sql没有复用差的计划
MySQL [oceanbase]>  select plan_id, operator, name, rows, cost from gv$ob_plan_cache_plan_explain where tenant_id=1002 and SVR_IP='172.16.100.137' and SVR_PORT=2882 and plan_id=2185;
+---------+-------------------------+---------------+--------+---------+
| plan_id | operator                | name          | rows   | cost    |
+---------+-------------------------+---------------+--------+---------+
|    2185 | PHY_PX_FIFO_COORD       | NULL          | 200002 | 1140163 |
|    2185 |  PHY_PX_REDUCE_TRANSMIT | NULL          | 200002 |  797398 |
|    2185 |   PHY_GRANULE_ITERATOR  | NULL          | 200002 |   26292 |
|    2185 |    PHY_TABLE_SCAN       | OB_PLAN_TEST1 | 200002 |   26292 |
+---------+-------------------------+---------------+--------+---------+
4 rows in set (0.01 sec)MySQL [oceanbase]>  select plan_id, operator, name, rows, cost from gv$ob_plan_cache_plan_explain where tenant_id=1002 and SVR_IP='172.16.100.137' and SVR_PORT=2882 and plan_id=2188;
+---------+----------------+----------------------------------+------+------+
| plan_id | operator       | name                             | rows | cost |
+---------+----------------+----------------------------------+------+------+
|    2188 | PHY_TABLE_SCAN | OB_PLAN_TEST1(IDX_OB_PLAN_TEST1) |    1 |    6 |
+---------+----------------+----------------------------------+------+------+
1 row in set (0.00 sec)

结论:

1.对于这种因为复用计划导致的sql执行效率降低的情况,把plan cache中该sql的计划刷掉,重新解析下就可以。

2.4.0之后有了curso_sharing参数,可以根据业务情况决定是否使用(能否接受该类sql的硬解析),也可以解决相应的情况。

3.绑定outline固定计划,这个当然也会有一定负面影响,比如大账号走回表的代价是否可以接受。tip:对于一些多表关联的hint绑定要经过一些判断,比如a表left join b表,正常a数据量少,b数据量大,绑定走索引和nest loop的hint没有问题,但是如果a表传入大账号的时候,a表数据量大了之后效率会急剧下降,这时候可以只绑定索引的hint,让优化器自己去选择连接方式。

可以从版本的递进和发展我们也能看到ob在不断的完善,虽然仍然还存在问题,需要不断的打磨、进步,但是数据库的发展不是一蹴而就的,ob的快速迭代优化,是肉眼可以看得见的,希望ob越来越成熟、稳定吧。

行之所向,莫问远方。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/746424.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

被军训到的两天

1.gradle7.6.1 1.安装gradle7.6.1,一定要注意的是&#xff0c;使用的JDK是否能用&#xff0c;比如gradle7.6.1用的是JDK11。 2. F:/sofer....是Gradle自己的仓库地址&#xff0c;注意不能和maven使用一样的仓库。 使用specified location,可以避免下本项目的gradle版本&…

如何更改SonarQube的JDK版本

如何更改SonarQube的JDK版本 当需要升级或更换SonarQube所使用的JDK版本时&#xff0c;可以按照以下步骤进行操作&#xff1a; 第一步&#xff1a;确定新JDK的安装路径 首先&#xff0c;您需要找到您打算使用的JDK的安装路径。这通常是一个包含JDK各种工具和库的文件夹。请确…

ego - 人工智能原生 3D 模拟引擎——基于AI的3D引擎,可以做游戏、空间计算、元宇宙等项目

1. 产品概述:Ego是一款AI本地化的3D模拟引擎,旨在让非技术创作者通过自然语言生成逼真的角色、3D世界和交互式脚本。该平台提供了创建和分享游戏、虚拟世界和交互体验的功能。 2. 定位:Ego定位于解决开放世界游戏和模拟的三大难题:难以编写游戏脚本、非玩家角色无法展现人…

性能测试-Redis

一、测试注意点 1、缓存预热 如果程序初次运行&#xff0c;此时由于数据尚未加载到缓存&#xff0c;则程序的响应时间会明显变长 注意事项&#xff1a; 性能测试的时候 出现 非常不稳定的现象程序刚启动&#xff0c;它的性能 明显 低于 已经运行一段时间的 1.1 测试缓存没…

基于SQL语句的数据脱敏实现方法

文章目录 要解决什么背景Jsqlparser安全系统难点目标 方法语法树遍历实现初始化第一轮第二轮第三轮 总结 要解决什么 企业进行软件开发、数据分析、数据查询时&#xff0c;不可避免的涉及到数据安全的问题&#xff0c;不同人员能看到的数据不同&#xff0c;如何识别哪些敏感数…

linux系统关闭防火墙和SELINUX及配置网络

一&#xff0c;关闭防火墙和SELINUX 当我们进入界面后&#xff0c;输入用户名root&#xff0c;以及密码&#xff0c;密码我们是看不见的 然后输入指令cat -n /etc/sysconfig/selinux &#xff08;注意空格&#xff09; 输入指令 vi /etc/sysconfig/selinux &#xf…

【Python】进阶学习:一文了解NotImplementedError的作用

【Python】进阶学习&#xff1a;一文了解NotImplementedError的作用 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448; 希望…

Hashtable、HashMap、TreeMap的区别

了解 Hashtable、HashMap、TreeMap 1&#xff09;Hashtable 是一个比较古老的实现&#xff0c;随 Java 1.0 引入。 它是同步的&#xff0c;这意味着它是线程安全的&#xff0c;但这也意味着它通常比非同步的实现&#xff08;如 HashMap &#xff09;慢。 不允许使用 null 键…

x264编码器 API 函数介绍

x264 x264是一个开源的视频编码库,用于将视频压缩为H.264/AVC(Advanced Video Coding)格式。它是一种广泛使用的视频编码标准,能够提供高质量的视频压缩和较低的比特率。 x264库提供了一个编码器,可以将原始视频序列转换为H.264/AVC压缩的比特流。它实现了各种H.264编码算…

【从Python基础到深度学习】12. 封包、解包

封包 将多个值赋值给一个变量时&#xff0c;Python 会自动将这些值封装成元组&#xff0c;这个特性称之为封包 a 1, 2, 3, 4 print(a) 解包 所有可迭代对象都支持解包 str list tuple dict set reversed range zip enumerate 赋值过程中的解包赋值符号左边变量和右边可迭代…

MongoDB实战面试指南:常见问题一网打尽

码到三十五 &#xff1a; 个人主页 心中有诗画&#xff0c;指尖舞代码&#xff0c;目光览世界&#xff0c;步履越千山&#xff0c;人间尽值得 ! MongoDB是一款流行的非关系型数据库&#xff0c;以其高效、可扩展的特性受到开发者的青睐。了解MongoDB的架构、存储引擎和数据结…

ETH共识升级之路

简介 根据我们之前的介绍&#xff0c;了解到ETH网络的共识方式&#xff0c;已经从 PoW 切换到了 PoS&#xff0c;今天我们就回顾下升级之路&#xff0c;以及升级带来的影响 最早的共识机制 PoW 以太坊创建之初采用了类似比特币的工作量证明机制&#xff0c;即矿工通过计算哈希函…

java房屋中介(java+SQL2000)-391-(源码+说明资料)

转载地址: http://www.3q2008.com/soft/search.asp?keyword391 任务及要求&#xff1a;  1&#xff0e;设计&#xff08;研究&#xff09;内容和要求&#xff08;包括设计或研究内容、主要指标与技术参数&#xff0c;并根据课题性质对学生提出具体要求&#xff09;  本系统…

知识图谱中的数据服务是什么?

随着信息时代的飞速发展&#xff0c;数据已经成为了各行各业的重要资源。知识图谱作为大数据时代的一种新型数据组织形式&#xff0c;能够将分散、无序的数据进行结构化处理&#xff0c;并建立起相互之间的关系&#xff0c;从而更好地满足人们对知识的需求。而在知识图谱中&…

CircuitBreaker熔断器

CircuitBreaker熔断器 1、Hystrix目前也进入维护模式 ​ Hystrix是一个用于处理分布式系统的延迟和容错的开源库&#xff0c;在分布式系统里&#xff0c;许多依赖不可避免的会调用失败&#xff0c;比如超时、异常等&#xff0c;Hystrix能够保证在一个依赖出问题的情况下&…

C++演变历史

C 从 C 98 版本到今年确定的 C23&#xff0c;共经历了 6 个版本的迭代。上面这张图里&#xff0c;列出了每次版本更新变化的内容。顶部黑体字的大小说明了版本变化的大小&#xff0c;其中 C14 是字体最小&#xff0c;这个版本是 C11 的增量版本&#xff0c;之所以没有大的变动&…

Server-Sent Events (SSE) 实现从服务器到客户端的实时数据流

前期回顾 避免阻塞主线程 —— Web Worker 示例项目-CSDN博客https://blog.csdn.net/m0_57904695/article/details/136721297?spm1001.2014.3001.5501 目录 CSDN 彩色之外 &#x1f4dd; 前言 &#x1f6e0;️ 安装 ✂️ 运行服务器 ✂️ 运行index.html ♻️ 贡献…

身份证查询-身份认证-javascript实名认证接口-

翔云身份证实名认证接口将与网络平台携手共筑信息安全防线&#xff0c;守护每一笔交易的真实可信&#xff0c;助力您的企业在数字化浪潮中稳健前行&#xff01; 以下是javascript语言调用翔云身份证实名认证API的代码&#xff1a; var form new FormData(); form.append("…

引领短剧风尚,打造全新观影体验——短剧APP开发之旅

随着移动互联网的迅猛发展&#xff0c;短视频和短剧成为了大众休闲娱乐的新宠。为了满足用户对于高质量、快节奏内容的需求&#xff0c;我们决定开发一款全新的短剧APP&#xff0c;为用户带来前所未有的观影体验。 这款短剧APP将集合丰富多样的短剧资源&#xff0c;涵盖各种题…

了解什么是 Redis 的雪崩、穿透和击穿?Redis 崩溃之后会怎么样?系统该如何应对这种情况?如何处理 Redis 的穿透?

目录 一、面试官心理分析 二、面试题剖析 1. 缓存雪崩 2. 缓存穿透 3. 缓存击穿 一、面试官心理分析 其实这是问到缓存必问的&#xff0c;因为缓存雪崩和穿透&#xff0c;是缓存最大的两个问题&#xff0c;要么不出现&#xff0c;一旦出现就是致命性的问题&#x…