表t_busi_main_presend2建了索引T_BUSI_MAIN_PRESEND2_SHSTATUS在SHSTATUS字段,SHSTATUS char(1) default '0',只有2个值 '0' ,'1'。初始值为‘0’,处理之后为‘1’,表中几十万数据,大部分为‘1’,现在有8条为‘0’。
现在,建索引(类型为normal,不能bitmap,会锁)后,下面语句竟然是全表!
select * from t_busi_main_presend2 where shstatus='0'
于是,我:
1.重新分析表之后继续执行,还是不行:
analyze table t_busi_main_presend2 compute statistics;
2.重建索引,仍然不行:
alter index T_BUSI_MAIN_PRESEND2_SHSTATUS rebuild;
3.清空shar pool还是不行:
alter system flush shared_pool
这三种都不行,就先删除表的统计,然后不要分析表,再看看走不走索引:
begin
DBMS_STATS.delete_table_stats(ownname => 'YDSOFT_TEST',tabname => 'T_MT');
end;
我自己这样之后,走索引了。
另外,在PL/SQL中用F5是看不到执行计划的 统计信息的,
select * from table ( dbms_xplan.display_cursor('SQL_ID')) 这种方法能看到
sql_id 自己到 V$SQL 里面捞去,或者到em中看
经过高人指点,有一下几种方案:
2.一般可行的方法:
1.由于该字段1值很多,0值很少,那么
①先删除之前该索引的统计信息
②按表数量的1%来采样收集统计信息
采样后:
查1的,走全表;查0的,走索引('YDSOFT_TEST'是owner。注意收集1%那么下面ESTIMATE_PERCENT=>1后面不能要%,否则会
ORA-06550: 第 2 行, 第 114 列:
PLS-00103: 出现符号 "%"在需要下列之一时:
) , * & = - + < / > at in is
mod remainder not rem <an exponent (**)> <> or != or ~= >= <=
<> and or like LIKE2_ LIKE4_ LIKEC_ between || multiset
member SUBMULTISET_
符号 "%" 被忽略。
)。这是正确的结果:
参数解释:
'YDSOFT_TEST'是owner
cascade=true表示
ESTIMATE_PERCENT=>1 索引也做分析这里的百分比是约小越好,中间原因太复杂了,没听老师讲明白。“桶”那个问题(在下面),不太明白。
method_opt 是表关联分析
第一句是删除索引的统计
SQL> begin
2 DBMS_STATS.delete_index_stats(ownname => 'YDSOFT_TEST',indname => 'T_BUSI_MAIN_PRESEND2_SHSTATUS');
3 end;
4 /
begin
DBMS_STATS.GATHER_TABLE_STATS('YDSOFT_TEST', 'T_BUSI_MAIN_PRESEND2', DEGREE=>3, CASCADE=>TRUE,ESTIMATE_PERCENT=>1 ,no_invalidate => false);
end;
2.此方法对于自动执行的系统中不太实用,但是自己手动操作一些东西的时候还是可以用的
在pl/sql“解释计划窗口”中,选择 “优化器目标”(选择/规则/第一行/所有行),分别选,看哪个走索引,最后确定 规则/第一行 走索引,此时可以加 /*+rule*/ 使其强制走索引。
select /*+rule*/* from t_busi_main_presend2 where shstatus='0'
update /*+rule*/t_busi_main_presend2 set shstatus='1' where shstatus='0' and id<>'504808'
笔记,关于采样量:
采样越大,是因为不同值太多
值太多,反而值越小越好
就把它看成个厂房的空间吧
如果你有3个值,只需要2个桶就够了,打个比方
比如值为1,占比90%,那不为1人只占10%,当然走索引了
当然,这里的桶不存数据,只存数据规模
也就是说生成插计划的时候,先判断是否有HINT,再看表规模,再看数据直方图中来判断目标数据的规模
其实就是数据分布
比如1值占比,数据分散性
这个和IO都是相尖的
相关
直方图,一是数据占比,二是数据分散性的一个指标
高度还没看
扫描 数字越大越快,不是指表分析,是全表取样扫描。我特指这种情况,不是表分析。
select * from tablename sample(95) order by rowid desc;
备注:此语句sample后面跟的数字越大,扫描速度越快。
以上语句,从一个很大的表中,快速扫描到 最后插入的数据,非常有效。【其实这个也是基于,表分析的结果,筛选的】