我有一张表有三个字段,
startip(number) endip (number) area(varchar2)
数据量共有7万条左右,我在STARTIP, ENDIP上建有索引
create index WORLDIP_IP_INDEX on WORLDIP (STARTIP, ENDIP)
tablespace USERS
pctfree 10
initrans 2
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
我去执行查询的时候,为什么有的时候用了索引,有的时候没有用索引呢?
查询语句如下:
select AREA from worldip T where 2068239936 between T.startip and T.endip
小弟oracle菜鸟,请各路神仙高手帮帮我……
startip(number) endip (number) area(varchar2)
数据量共有7万条左右,我在STARTIP, ENDIP上建有索引
create index WORLDIP_IP_INDEX on WORLDIP (STARTIP, ENDIP)
tablespace USERS
pctfree 10
initrans 2
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
我去执行查询的时候,为什么有的时候用了索引,有的时候没有用索引呢?
查询语句如下:
select AREA from worldip T where 2068239936 between T.startip and T.endip
小弟oracle菜鸟,请各路神仙高手帮帮我……
执行计划
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=56 Card=15210 Byte
s=258570) 1 0 TABLE ACCESS (FULL) OF 'WORLDIP' (TABLE) (Cost=56 Card=152
10 Bytes=258570)统计信息
----------------------------------------------------------
0 recursive calls
0 db block gets
249 consistent gets
0 physical reads
0 redo size
467 bytes sent via SQL*Net to client
435 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
以上是小弟的执行计划,也不晓得全不全
select * from worldip t where 2068239936 >= startip and 2068239936 <=endip
执行计划
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=56 Card=15210 Byte
s=258570) 1 0 TABLE ACCESS (FULL) OF 'WORLDIP' (TABLE) (Cost=56 Card=152
10 Bytes=258570)统计信息
----------------------------------------------------------
1 recursive calls
0 db block gets
249 consistent gets
0 physical reads
0 redo size
467 bytes sent via SQL*Net to client
435 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
======================
总的数据量多少?返回数据的百分比多大?如果 selectivity 太低,索引不会起作用。
create unique index WORLDIP_IP_INDEX on WORLDIP (STARTIP, ENDIP, area) ;
/
begin
--收集统计信息
dbms_stats.gather_table_stats(user, 'WORLDIP', CASCADE=>TRUE);
end;
/
2. sql语句写成:select * from worldip t where startip <= 2068239936 and endip >= 2068239936;这个写法比较好看3. 若你的startip, endip2个字段的数值分布不均匀,10g的CBO无法收2个字段上的直方图,可用hint强制使用索引select /*+ index(t WORLDIP_IP_INDEX) */ * from worldip t where startip <= 2068239936 and endip >= 2068239936;
按照你得做了,表是按照你写的那个语句分析的,可是还是那样的结果,执行计划没有变,基本上一样。
我这个表里面的数据室一次性加入的,大约7万条,以后就固定了,基本上没有插入和删除,每次都是查询出一条数据,
为何排在表前面的字段,查询的时候会用到索引,而靠后的数据就不行了呢?我在网上查到,貌似是oracle 10g采用的默认方式的基于代价的方式,当oracle发现用索引的代价比用全表扫描的代价高时,就会自动采用全表扫描的方式……但是我就是想提高查询的效率,想让查询每条数据的开销基本上都差不多,这个要怎么解决? 我想oracle肯定有相应的办法,只是我太菜不晓得,所以只能求救各位大哥了
用这个呢? 效果如何?
你之前建的索引属于多码索引,如果startip和endip是主码的话可能影响不大,否则进行范围查询时使用辅助索引速度会非常的慢。如果你那张表更新的频率不频繁的话,建议使用位图索引。