有一个表中有50多万行数量,有一列中存了三个值,分别是0,1,4,现在查询时,当条件为0时使用全表扫描,为1和4时使用了该列的索引,请大家为我解惑。select t.* from mytable t
where t.vc_flag='0'
已选择36403行,PLSQL中执行时间2.578秒
-------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 653K| 132M| 4891 (3)| 00:00:59 |
|* 1 | TABLE ACCESS FULL| MYTABLE | 653K| 132M| 4891 (3)| 00:00:59 |
-------------------------------------------------------------------------------------------select t.* from mytable t
where t.vc_flag='1'
已选择20行,PLSQL中执行时间0.125秒
------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 213 | 1 (0) | 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID | MYTABLE | 1 | 213 | 1 (0) | 00:00:01 |
| 2 | BITMAP CONVERSION TO ROWIDS| | | | | |
|* 3 | BITMAP INDEX SINGLE VALUE | SYS_C00105059 | | | | |
------------------------------------------------------------------------------------------------------select t.* from mytable t
where t.vc_flag='4'
已选择512599行,PLSQL中执行时间0.125秒
------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 713 | 148K| 98 (0) | 00:00:02 |
| 1 | TABLE ACCESS BY INDEX ROWID | MYTABLE | 713 | 148K| 98 (0) | 00:00:02 |
| 2 | BITMAP CONVERSION TO ROWIDS| | | | | |
|* 3 | BITMAP INDEX SINGLE VALUE | SYS_C00105059 | | | | |
------------------------------------------------------------------------------------------------------
解决方案 »
- oracle 数据导入到sql server中
- form的*.MMB如何传全局变量给report
- NamedParameterJdbcTemplate 循环更新数据失败
- 在pl/sql里修改system的密码.则提示: 提示“ORA-04042:过程、函数、程序包或程序包体不存在”,
- 新手问一个关于SQL PLUS信息输出格式的简单问题,大家请进来看看吧。
- 触发器的问题
- PL/SQL Developer的连接问题
- 一个触发器的问题,当插入A表时,再插入B表
- logminer 字典的问题?高手进
- oracle7.3 oracle 805如何导入 oracle815 在线急等
- oracle 层次查询
- 能批量修改某个字段的值的一部分吗?
会不会vc_flag的类型有关啊?
用下面这样的试试
select t.* from mytable t
where t.vc_flag=0
--你的vc_flag是 not null吗?如果允许为null的话可能会不走索引
select /*+index(table_name index_name)*/
t.* from mytable t
where t.vc_flag=0
create table t_test_bitmap
(id number,
cnt number);
insert into t_test_bitmap
select rownum ,mod(rownum,5) from dual connect by rownum<500000;
commit;
CREATE BITMAP INDEX t_test_bitmap1 on t_test_bitmap(cnt);SQL> exec dbms_stats.gather_table_stats(ownname => 'scott',tabname => 't_test_bitmap',estimate_percent => 10,method_opt=> 'for all indexed columns') ;
PL/SQL procedure successfully completed
SQL> exec dbms_stats.gather_index_stats(ownname => 'scott',indname => 't_test_bitmap1',estimate_percent => '10',degree => '4') ;
PL/SQL procedure successfully completed
SQL> explain plan for select * from t_test_bitmap t where t.cnt=0;
Explained
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 241495815
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 99930 | 1561K| 217 (6)| 00:00:0
|* 1 | TABLE ACCESS FULL| T_TEST_BITMAP | 99930 | 1561K| 217 (6)| 00:00:0
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("T"."CNT"=0)
13 rows selected
如果是这样的话,应该不在vc_flag建立索引,好像意义不大,建议考虑下语句是否作调整
把你的表进行分析下,可能你的优化规则是采取的choose的方式,如果在数据字典里面没有你查询对象的统计信息他就会选择RBO,如果有统计信息他就选择CBO
Oracle把一个代价引擎(Cost Engine)集成到数据库内核中,用来估计每个执行计划需要的代价,该代价将每个执行计划所耗费的资源进行量化,从而CBO可以根据这个代价选择出最优 的执行计划。一个查询耗费的资源可以被分成3个基本组成部分:I/O代价、CPU代价、network代价。I/O代价是将数据从磁盘读入内存所需的代 价。访问数据包括将数据文件中数据块的内容读入到SGA的数据高速缓存中,在一般情况下,该代价是处理一个查询所需要的最主要代价,所以我们在优化时,一 个基本原则就是降低查询所产生的I/O总次数。CPU代价是处理在内存中数据所需要的代价,如一旦数据被读入内存,则我们在识别出我们需要的数据后,在这 些数据上执行排序(sort)或连接(join)操作,这需要耗费CPU资源。
RBO
在ORACLE7之前,主要是使用基于规则的优化器。ORACLE在基于规则的优化器中采用启发式的方法(Heuristic Approach)或规则(Rules)来生成执行计划。例如,如果一个查询的where条件(where clause)包含一个谓词(predicate,其实就是一个判断条件,如”=”, “>”, ”<”等),而且该谓词上引用的列上有有效索引,那么优化器将使用索引访问这个表,而不考虑其它因素,如表中数据的多少、表中数据的易变性、索引的 可选择性等。此时数据库中没有关于表与索引数据的统计性描述,如表中有多上行,每行的可选择性等。优化器也不考虑实例参数,如multi block i/o、可用排序内存的大小等,所以优化器有时就选择了次优化的计划作为真正的执行计划,导致系统性能不高。
select /*+ rule */ t.* from mytable t
where t.vc_flag='0'
最后查到了速度慢的原因,是因为表初始化空间太小,导致记录在插入后磁盘碎片过多,所以查询速度特别慢,将表的初始化空间调整到600m后,速度提高了10倍以上,希望这个教训能让大家了解表的初始化空间对表的速度影响有多大。问题解决,结贴!