关于ORACLE索引的一个效率测试
索引测试语句
select user_number,opp_user_number,call_type,start_time,duration,lac_id,cell_id,esn from jf.dr_gsm_793_20081001@jxcb1 where user_number='15907932556' union all
select user_number,opp_user_number,call_type,start_time,duration,lac_id,cell_id,esn from jf.dr_gsm_793_20081002@jxcb1 where user_number='15907932556';
共91条记录
1.测试位图索引和普通索引的速度
建立位图索引
create bitmap index gsm_20081001_ind on DR_GSM_793_20081001(user_number);
create bitmap index gsm_20081002_ind on DR_GSM_793_20081002(user_number);
·耗数7,基数16
建立普通索引
CREATE index gsm_20081001_ind on DR_GSM_793_20081001(user_number);
CREATE index gsm_20081002_ind on DR_GSM_793_20081002(user_number);
·耗数40,基数32
--结论:在没有执行delete,update,insert into的时候bitmap比正常的索引要有效率
2.测试普通组合索引
建立普通组合索引
CREATE index gsm_20081001_ind on DR_GSM_793_20081001(user_id,user_number);
CREATE index gsm_20081002_ind on DR_GSM_793_20081002(user_id,user_number);
使用user_number查询并没有用到索引
·耗数84282,基数32
使用user_id查询就用到了索引
·耗数40,基数32
select user_number,opp_user_number,call_type,start_time,duration,lac_id,cell_id,esn from srcb.dr_gsm_793_20081001 where user_Id>'400010489928' AND user_number>'15907932556' union all
select user_number,opp_user_number,call_type,start_time,duration,lac_id,cell_id,esn from srcb.dr_gsm_793_20081002 where user_id>'400010489928' AND user_number>'15907932556';
查询user_id,user_number按顺序是
·耗费55,基数43
查询user_number,user_id就也使用到索引
·耗费55,基数43
增加索引字段
CREATE index gsm_20081001_ind on DR_GSM_793_20081001(user_id,user_number,esn);
CREATE index gsm_20081002_ind on DR_GSM_793_20081002(user_id,user_number,esn);
查询user_id,user_number按顺序是
·耗费59,基数43
换成每个字段单独建立索引
CREATE index gsm_20081001_ind on DR_GSM_793_20081001(user_id);
CREATE index gsm_20081002_ind on DR_GSM_793_20081002(user_id);
CREATE index gsm_20081003_ind on DR_GSM_793_20081001(user_number);
CREATE index gsm_20081004_ind on DR_GSM_793_20081002(user_number);
按user_id,user_number的顺序
·耗费1548,基数43
按user_number,user_Id的顺序
·耗费1548,基数43
增加单独索引
CREATE index gsm_20081005_ind on DR_GSM_793_20081001(opp_user_number);
CREATE index gsm_20081006_ind on DR_GSM_793_20081002(opp_user_number);
查询的时候没有用的opp_user_number
·耗费1548,基数43
查询的时候用到了opp_user_number
select user_number,opp_user_number,call_type,start_time,duration,lac_id,cell_id,esn from srcb.dr_gsm_793_20081001 where user_number>'15907932556' AND user_Id>'400010489928' AND opp_user_number>'15907932556' UNION ALL
select user_number,opp_user_number,call_type,start_time,duration,lac_id,cell_id,esn from srcb.dr_gsm_793_20081002 WHERE user_number>'15907932556' AND user_Id>'400010489928' AND opp_user_number>'15907932556' ;
·耗费1548,基数43
查询的时候去掉了索引
DROP INDEX gsm_20081005_ind;
DROP INDEX gsm_20081006_ind;
查询多字段,但就一个字段有索引
CREATE index gsm_20081002_ind on DR_GSM_793_20081002(user_id);
CREATE index gsm_20081001_ind on DR_GSM_793_20081001(uSER_ID);
·耗费1548,基数43
--结论: 1.组合索引中如果没有用的索引的第一个列字段,就不会调用索引;
2.如果都用到组合索引中的2个字段,不管顺序如何,速度都是一样的 ;
3.增加组合索引的索引字段查询会变慢;
4.如果where条件中用到了2个列字段,而且这2个都单独建立了索引,其速度是没有给这2个字段建立组合索引的速度快;
5.如果一个字段有做索引但在where条件中没有使用到是不影响速度的;
6.在where条件中如果用到了多字段,但只有一个字段做个索引,其查询的速度是这个字段所在的位置是没有关系的,就算其它的其它的字段没有做索引,其速度都是以做了索引的字段的查询速度为准;
3.测试索引名的长度
CREATE index dr_gsm_793_20081001_index on DR_GSM_793_20081001(user_number);
CREATE index dr_gsm_793_20081002_index on DR_GSM_793_20081002(user_number);
·耗数40,基数32 --
--结论:说明索引名的长度是没有关系的
4.测试没有where条件下的索引作用
CREATE index dr_gsm_793_20081001_index on DR_GSM_793_20081001(user_number);
查询select * from DR_GSM_793_20081001;
--结论:是全表SCAN,并没有用到索引.
5.建立索引的名称必须是字母开头,而不是数字。
=========================================================
这样分析后,我给每个表都建立了
CREATE bitmap INDEX index1_20081222 ON dr_gsm_793_20081222(USER_NUMBER);
CREATE bitmap INDEX index2_20081222 ON dr_gsm_793_20081222(opp_USER_NUMBER);
CREATE bitmap INDEX index3_20081222 ON dr_gsm_793_20081222(esn);
CREATE bitmap INDEX index4_20081222 ON dr_gsm_793_20081222(netcall_flag);
但是我发现在select * from user_ind_columns
INDEX_NAME TABLE_NAME COLUMN_NAME COLUMN_POSITION COLUMN_LENGTH CHAR_LENGTH DESCEND
INDEX1_20081201 DR_GSM_793_20081201 USER_NUMBER 1 15 15 ASC
INDEX2_20081201 DR_GSM_793_20081201 OPP_USER_NUMBER 1 30 30 ASC
INDEX3_20081201 DR_GSM_793_20081201 ESN 1 25 25 ASC
INDEX4_20081201 DR_GSM_793_20081201 NETCALL_FLAG 1 22 0 ASC
这个netcall_flag的索引是没有用的,基本没有用到,在user_ind_columns中的char_length是0,是不是索引有问题?
还有这个select * from DR_GSM_793_20081201 where user_number>0也没有用到索引(这个0在user_number中不存在)
但是select * from DR_GSM_793_20081201 where user_number>15907932556就存在(这个15907932556在user_number中不存在)
有高手来分析下不,大家讨论下呢