Oracle - 即使我有查询索引也进行全表扫描

问题描述 投票:0回答:1
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 没有选择我创建的索引。 请在此提供帮助,提前致谢

sql database oracle indexing full-table-scan
1个回答
0
投票

为了提高索引被利用的可能性,您可以考虑简化查询并针对索引使用进行优化。这是您的查询的修改版本:

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_EXISTSJSON_EXISTS 条件,因为在子查询中应用这些条件应该适当地过滤结果。

通过直接比较 JSON 值来简化条件,而不是在 WHERE 子句中使用复杂的 JSON_EXISTSJSON_VALUE 函数。直接比较更有可能是索引友好的。

WHERE 子句中保留 CAST((JSON_VALUE(json_col1, '$.id')) AS INTEGER) > 1 条件,过滤掉 ID 小于或等于 1 的结果。

JSON_VALUE 函数调用添加了别名以提高可读性。

通过以这种方式简化和构造查询,数据库优化器更有可能认识到有效利用索引的机会。但是,请确保分析执行计划以确认索引是否确实按预期被使用。

© www.soinside.com 2019 - 2024. All rights reserved.