SELECT *
FROM
( SELECT
key1,
JSON_VALUE(json_col1, '$.jsonElement2'),
JSON_VALUE(json_col1, '$.date1') ,
JSON_VALUE(json_col1, '$.date2'),
json_col1,
created
FROM
table_name
WHERE NOT JSON_EXISTS ( "json_col1" FORMAT JSON, '$?( (@.jsonElement1 in ("NAME")) )'
)
AND JSON_EXISTS ( "json_col1" FORMAT JSON, '$?( (@.jsonElement2 in ("SAMPLE"))
&& (@.jsonElement3 in ("CORE")) )' )
AND JSON_EXISTS ( "json_col2" FORMAT JSON, '$?( (
(@.json_element5 == "" || (!exists(@.json_element6))) ))'
)
AND CAST((JSON_VALUE(json_col1, '$.id')) AS INTEGER) > 1
ORDER BY
CAST((JSON_VALUE(json_col1, '$.id')) AS INTEGER)
)
WHERE rownum <= 10
我的索引是:
CREATE INDEX "SCHEMA"."INDEX_ONE" ON "SCHEMA"."TABLE_NAME"
(
JSON_VALUE("json_col1" FORMAT JSON , '$.jsonElement1' RETURNING VARCHAR2(300) ERROR ON ERROR NULL ON EMPTY),
JSON_VALUE("json_col1" FORMAT JSON , '$.jsonElement2' RETURNING VARCHAR2(300) ERROR ON ERROR NULL ON EMPTY),
JSON_VALUE("json_col1" FORMAT JSON , '$.jsonElement3' RETURNING VARCHAR2(300) ERROR ON ERROR NULL ON EMPTY),
JSON_VALUE("json_col2" FORMAT JSON , '$.json_element5' RETURNING VARCHAR2(300) ERROR ON ERROR NULL ON EMPTY),
JSON_VALUE("json_col2" FORMAT JSON , '$.json_element6' RETURNING VARCHAR2(300) ERROR ON ERROR NULL ON EMPTY),
JSON_VALUE("json_col1" FORMAT JSON , '$.id' RETURNING VARCHAR2(300) ERROR ON ERROR NULL ON EMPTY)
)
提到我正在使用的查询和索引。 当我检查解释计划时,不知道为什么 Oracle 没有选择我创建的索引。 请在此提供帮助,提前致谢
为了提高索引被利用的可能性,您可以考虑简化查询并针对索引使用进行优化。这是您的查询的修改版本:
SELECT *
FROM (
SELECT key1,
JSON_VALUE(json_col1, '$.jsonElement2') AS jsonElement2_val,
JSON_VALUE(json_col1, '$.date1') AS date1_val,
JSON_VALUE(json_col1, '$.date2') AS date2_val,
json_col1,
created
FROM table_name
WHERE CAST((JSON_VALUE(json_col1, '$.id')) AS INTEGER) > 1
AND JSON_VALUE(json_col1, '$.jsonElement1') = 'NAME'
AND JSON_VALUE(json_col1, '$.jsonElement2') = 'SAMPLE'
AND JSON_VALUE(json_col1, '$.jsonElement3') = 'CORE'
AND (JSON_VALUE(json_col2, '$.json_element5') = '' OR NOT JSON_EXISTS(json_col2, '$.json_element6'))
ORDER BY CAST((JSON_VALUE(json_col1, '$.id')) AS INTEGER)
) WHERE rownum <= 10;
在此修改中:
我从外部查询中删除了 NOT JSON_EXISTS 和 JSON_EXISTS 条件,因为在子查询中应用这些条件应该适当地过滤结果。
通过直接比较 JSON 值来简化条件,而不是在 WHERE 子句中使用复杂的 JSON_EXISTS 和 JSON_VALUE 函数。直接比较更有可能是索引友好的。
WHERE 子句中保留 CAST((JSON_VALUE(json_col1, '$.id')) AS INTEGER) > 1 条件,过滤掉 ID 小于或等于 1 的结果。
为 JSON_VALUE 函数调用添加了别名以提高可读性。
通过以这种方式简化和构造查询,数据库优化器更有可能认识到有效利用索引的机会。但是,请确保分析执行计划以确认索引是否确实按预期被使用。