为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。
【DM版本】: DM8
【操作系统】:
【CPU】:
【问题描述】*:
--创建表和数据
create table DMHR.t_index(ci int ,cv varchar2(100));
begin
for i in 10001..100000 loop
insert into t_index values(i,to_char(i));
if mod(i,1000)=0 then
commit;
end if;
end loop;
commit;
end;
--创建索引
CREATE INDEX DMHR.T_INDEX_IDX ON DMHR.T_INDEX (substr(CV,1,2));
--查询计划
explain SELECT * FROM DMHR.T_INDEX WHERE CV='12'
--执行计划为走到T_INDEX_IDX索引
1 #NSET2: [12, 2500, 64]
2 #PRJT2: [12, 2500, 64]; exp_num(3), is_atom(FALSE)
3 #SLCT2: [12, 2500, 64]; T_INDEX.CV = '12'
4 #CSCN2: [12, 100000, 64]; INDEX33555648(T_INDEX)
cv='12' 跟 substr(cv,1,2) = '12' 是不等价的
cv='12' 是该列的内容完整等于字符串12,而在本例中没有12字符的数据。
substr(cv,1,2) = '12' 是所有12开头的字符的列都匹配出来,在你此示例数据中接近1万的数据匹配出来,会造成二次回表(随机读致命),索引优化只是优化性能的一部分,没用好,反倒把性能搞差。
substr(CV,1,2)这个函数取出来的结果优化器认为全扫的更优,你试试用substr(CV,3,2),还有要使用函数索引,查询的时候要带上,
explain SELECT * FROM DMHR.T_INDEX WHERE substr(CV,3,2)='10'