搞清楚执行计划怎么干,那么看执行计划看啥?
1、看JOIN的方式
2、看表的访问方式,走全表,走索引
3、看有没有一些经常影响性能的操作,比如FILTER
4、看cardinality(rows)与真实的差距
不要太过于关注COST,COST是估算的,大不一定就慢,小不一定就快……当然比如COST很小,rows返回的都是很小的,很慢。那么,我们可能得考虑统计信息是不是过旧问题。
统计信息很重要,就说一个例子:

走了索引,COST很小,一切都很完美,但是AWR现实占80%的资源。一般啥情况?单纯从SQL上看,也就是这执行计划估计不对,自己测一下,很慢。也就是COST很小,ROWS很小,走索引,很完美的计划是错误的,那么很显然,基本就是统计信息导致的了。
实际第4步走sendtime索引,应该返回1689393行,但是执行计划估算返回1行,统计信息不准确,再次检查统计信息收集日期是5月前的。
SQL> SELECT COUNT(1) FROM MSP.T_MS_MEDIA_TASK WHERE SENDTIME >=TRUNC(SYSDATE,'dd') AND MONTHDAY = TO_CHAR(SYSDATE,'mmdd') ;
TO_CHAR(SYSDATE,'mmdd') ;
? COUNT(1)
----------
? ?1689393
收集统计信息,for all columns size repeat 保持原有直方图信息
?exec DBMS_STATS.GATHER_TABLE_STATS(ownname=>'MSP',tabname=>'T_MS_MEDIA_TASK',estimate_percent=>10,method_opt=>'for all columns size repeat', no_invalidate=>false,cascade=>true,degree => 10);
返回168万行,但是现有统计信息却让cbo认为是1行,这差别也太大了。
method_opt=>'for all columns size repeat', 这里说下,更新统计信息,最好使用for all columns size repeat...
repeat的好处是啥,比如列有直方图,会给你保留,列没有统计信息会按照for all columns size 1收集。。。其他原来怎么收就怎么收。
你用一个for all columns size 1或size skewonly,或者不写(auto)都可能改变原有统计信息的收集方式,都有可能影响SQL的执行效率。
高效访问结构让SQL更快,这个不说了,主要是建索引。如何建索引也是一个很复杂的问题,说一点,一般复合索引,等值查询条件频率高的,作为前导列较好。因为直接访问可能效率比>,<...等高,后者访问了还需要过滤。
下面看下影响优化器的参数导致的性能问题。
这是10g执行计划,一个视图是UNION ALL做的,全部走索引:

但是11.2.0.4全表扫描了。