0
点赞
收藏
分享

微信扫一扫

ORA-30553 ORA-01450 创建函数索引时提示

问题概述

在优化生产SQL,遇到一个使用函数过滤进行全表扫描的SQL,
从ASH执行计划上看,SQL的时间基本都消耗在这里了,使用使用函数索引进行优化

– 自定义函数创建索引报错ORA-30553
ORA-30553: The function is not deterministic

– 使用ONLINE创建时报错ORA-01450
ORA-00604: error occurred at recursive SQL level 1
ORA-01450: maximum key length (3215) exceeded

-- 创建函数索引的SQL 函数引用的列特别长
create index COGXXX.IDX_XXXID2 on COGXXX.TAB_XXX_XXX_XXX(
COGXXX.XX_FUN_MD5("XXXX_DATE"||TO_CHAR("XXXXTYPE")||"XXX_XXXX_CODE"||TO_CHAR("VXXXXXXXID")||TO_CHAR("PXXTYPE")||
TO_CHAR("ISXXXXXXX")||TO_CHAR("BXX_XXX_ID")||TO_CHAR("ISXXXYEAR")||DECODE("PXXTYPE",8,'',"PXY_XXX_NO")||
DECODE("PXXTYPE",8,'',"PXX_XXX_XXXX_CODE")||"CXXXX_XXXX_CODE"||"CXXX_AXXX_NO")
);

问题原因

1 自定义函数创建索引时需要加上deterministic定义
2 online创建索引会验收索引中的字段长度

解决方案

-- 创建函数索引的SQL 
create index COGXXX.IDX_XXXID2 on COGXXX.TAB_XXX_XXX_XXX(
COGXXX.XX_FUN_MD5("XXXX_DATE"||TO_CHAR("XXXXTYPE")||"XXX_XXXX_CODE"||TO_CHAR("VXXXXXXXID")||TO_CHAR("PXXTYPE")||
TO_CHAR("ISXXXXXXX")||TO_CHAR("BXX_XXX_ID")||TO_CHAR("ISXXXYEAR")||DECODE("PXXTYPE",8,'',"PXY_XXX_NO")||
DECODE("PXXTYPE",8,'',"PXX_XXX_XXXX_CODE")||"CXXXX_XXXX_CODE"||"CXXX_AXXX_NO")
);

-- 执行报错:该函数是不确定的(自定义的)
ORA-30553: The function is not deterministic

# 检查函数:
SYS@ORCL(ORCL): 2>   @source XX_FUN_MD5
      FUNCTION XX_FUN_MD5(
      v_chr IN VARCHAR2) RETURN VARCHAR2 IS
      retval varchar2(32); BEGIN
      retval := utl_raw.cast_to_raw(DBMS_OBFUSCATION_TOOLKIT.MD5(INPUT_STRING => v_chr)); RETURN retval; END;

# 加上deterministic重建函数
create or replace function COGXXX.XX_FUN_MD5(
v_chr IN VARCHAR2) RETURN VARCHAR2 deterministic
IS
retval varchar2(32); BEGIN
retval := utl_raw.cast_to_raw(DBMS_OBFUSCATION_TOOLKIT.MD5(INPUT_STRING => v_chr)); RETURN retval; END;
/


-- 再执行时报错:
create index COGXXX.IDX_XXXID2 on COGXXX.TAB_XXX_XXX_XXX(
COGXXX.XX_FUN_MD5("XXXX_DATE"||TO_CHAR("XXXXTYPE")||"XXX_XXXX_CODE"||TO_CHAR("VXXXXXXXID")||TO_CHAR("PXXTYPE")||
TO_CHAR("ISXXXXXXX")||TO_CHAR("BXX_XXX_ID")||TO_CHAR("ISXXXYEAR")||DECODE("PXXTYPE",8,'',"PXY_XXX_NO")||
DECODE("PXXTYPE",8,'',"PXX_XXX_XXXX_CODE")||"CXXXX_XXXX_CODE"||"CXXX_AXXX_NO")
) online;

ORA-00604: error occurred at recursive SQL level 1
ORA-01450: maximum key length (3215) exceeded


-- 解决方法是使用非标准块的表空间(例如8k-->64k)来存放索引
-- online创建索引时oracle计算了相关列的长度,但是不是函数返回的长度

解决方法:
不使用online,函数索引创建成功

举报

相关推荐

0 条评论