联系我们
18591797788
hubin@rlctech.com
北京市海淀区中关村南大街乙12号院天作国际B座1708室
18681942657
lvyuan@rlctech.com
上海市浦东新区商城路660号乐凯大厦26c-1
18049488781
xieyi@rlctech.com
广州市越秀区东风东路华宫大厦808号1608房
029-81109312
service@rlctech.com
西安市高新区天谷七路996号西安国家数字出版基地C座501
在企业级数据库运维中,索引是否生效直接影响查询性能,而 SQL 审计则是问题追溯的关键依据。近期技术团队在 OceanBase 测试环境中遇到两个典型问题:不同版本间 JSON 索引使用差异与SQL 审计 query_sql 字段为空。本文结合真实问题场景,从问题复现、原因分析到解决方案进行完整拆解。
环境:测试环境
OB 版本:4.2.5.5-1050200120250814144.2.5.5-105020012025081414
和4.3.5.2-102000162025051417
租户模式:ORACLE模式;
A. 同样的表,同样的创建索引的语句。在4255版本该表会走
JSON类型的字段索引。但是在4352反而不会走。是因为4352不支持JSON索引吗?
B. 刚刚测试的时候发现的,4255的
sqlaudit里query_sql都是null。为什么?
创建表结构
–4255
CREATE TABLE “GLGX” (
“BH” VARCHAR2(32 CHAR) NOT NULL ENABLE,
“FYDM” NUMBER(*,0) NOT NULL ENABLE,
“AJM” JSON,
CONSTRAINT “PK_GLGX_250914” PRIMARY KEY (“FYDM”, “BH”)
) COMPRESS FOR ARCHIVE REPLICA_NUM = 1 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0
—4352
CREATE TABLE “GLGX” (
“BH” VARCHAR2(32 CHAR) NOT NULL ENABLE,
“FYDM” NUMBER(*,0) NOT NULL ENABLE,
“AJM” JSON,
CONSTRAINT “PK_GLGX_1” PRIMARY KEY (“FYDM”, “BH”)
) COMPRESS FOR ARCHIVE REPLICA_NUM = 2 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE ENABLE_MACRO_BLOCK_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0

创建索引语句
—4255
CREATE INDEX “CONAN”.“IDX_GLGX_AJM_0” on “CONAN”.“GLGX” (
json_value(“AJM”,’$[0]’ RETURNING VARCHAR2 null on error)
) GLOBAL ;
–4352
CREATE INDEX “CONAN”.“IDX_GLGX_AJM_0” on “CONAN”.“GLGX” (
json_value(“AJM”,’$[0]’ RETURNING VARCHAR2 null on error)
) GLOBAL ;

数据导入
INSERT INTO CONAN.GLGX (BH,FYDM,AJM) VALUES (‘0562DBDD558111EFACB2E8611F528106’,1302,’[“202407121301200011”]’);
INSERT INTO CONAN.GLGX (BH,FYDM,AJM) VALUES (‘0562DBDD558111EFACB2E8611F528107’,1302,’[“202407121301200011”]’);
类似上述语句进行导入
explain查看逻辑执行计划
explain SELECT BH,FYDM,AJM FROM CONAN.GLGX WHERE ( JSON_VALUE(AJM, ‘$[0]’) IN (‘2024071213012123456’));

4255版本是走了JSON索引的,但是4352确没有走
查看物理实际的执行计划
查看对应planid

查看详细的物理执行计划

最终确认4255版本确实走了JSON索引,但是4352走的全表扫描。
获取两个ob版本对应执行的SELECT BH,FYDM,AJM FROM CONAN.GLGX WHERE ( JSON_VALUE(AJM, ‘[0]') IN ('2024071213012123456')); 获取语句的sqlaudit4352ob版本具体的优化信息 在4352版本执行: explain extended SELECT BH,FYDM,AJM FROM CONAN.GLGX WHERE ( JSON_VALUE(AJM, '[0]’ null on error) IN (‘2024071213012123456’));
explain extended SELECT BH,FYDM,AJM FROM CONAN.GLGX WHERE ( JSON_VALUE(AJM, ‘$[0]’ RETURNING VARCHAR2 null on error) IN (‘2024071213012123456’));
4352版本是可以使用JSON索引的
问题总结:建索引的时候有null on error ,查询的时候也要带上;建索引的时候不带null on error ,查询的时候也不能带。查询的时候需要和建索引的语法保持一致。
遗留问题:为何4255版本执行的时候没带null on error会走该JSON索引,4352版本执行的时候没带null on error却走全表不走JSON索引呢?
问题解析:425版本的小版本比较新,是修复后的版本,已修复版本为:435bp4及之后版本或者441及之后版本。
问题1:在4255版本该表会走JSON类型的字段索引。但是在4352反而不会走?
问题解析:本次 JSON 索引问题属于版本 BUG,升级至 4.3.5 BP4 或 4.4.1 及之后版本可彻底解决;同时,新版本会持续优化性能与兼容性,减少类似问题。
修复前:如果创建JSON索引带了null on error,那么执行语句JSON字段的过滤条件也得带null on error才会走JSON索引。没带null on error,执行语句JSON字段的过滤条件也必须不带null on error;
修复后:就不需要一一对应了,会自动识别。
问题2:sqlaudit里query_sql都是null?
问题解析:https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000003401600新增配置项 _enable_sql_audit_query_sql 普通租户查询 query_sql 为空,如果打开开关,对普通租户暴露 query_sql 信息,默认值 false,在非 SYS 租户下 query_sql 字段可能为空。
OceanBase 数据库 V4.2.5 BP2(oceanbase-4.2.5.2-102000122025011711)及之后的版本。)
后续我们还会持续分享数据库实战优化技巧,无论是 OceanBase 技术解析还是性能调优案例,都将第一时间呈现。如果你的业务中也遇到过类似难题,欢迎在评论区留言讨论,下次见!