索引优化使用(转)

提高索引查询效率;
  alter index idx_name rebuild nologging;

SQL优化器简介
  
  基于规则的优化器
  
  。总是使用索引
  。总是从驱动表开始(from子句最右边的表)
  。只有在不可避免的情况下,才使用全表扫描
  。任何索引都可以
  
  基于成本的优化器
  
  。需要表、索引的统计资料
  Analyze table customer compute statistics;
  Analyze table customer estimate statistics sample 5000 rows;
  。表中设置并行度、表分区
  
  优化器模式
  
  rule模式
  
  。总忽略CBO和统计信息而基于规则
  choose模式
  
  。Oracle根据情况选择rule or first_rows or all_rows
  first_rows 模式
  
  。基于成本,以最快的速度返回记录,会造成总体查询速度的下降或消耗更多的资源,倾向索引扫描,适合OLTP系统
  all_rows模式
  
  。基于成本,确保总体查询时间最短,倾向并行全表扫描
  
  例如:
  Select last_name from customer order by last_name;用first_rows时,迅速返回记录,但I/O量大,用all_rows时,返回记录慢,但使用资源少。
  
  调整SQL表访问
  
  全表扫描
  
  。返回记录:未排序表>40%,排序表>7%,建议采用并行机制来提高访问速度,DDS;
  
  索引访问
  
  。最常用的方法,包括索引唯一扫描和索引范围扫描,OLTP;
  
  快速完全索引扫描
  
  。访问索引中所有数据块,结果相当于全表扫描,可以用索引扫描代替全表扫描,例如:
  
  Select serv_id,count(* ) from tg_cdr01 group by serv_id;
  
  评估全表扫描的合法性
  
  如何实现并行扫描
  
  。永久并行化(不推荐)
  alter table customer parallel degree 8;
  
  。单个查询并行化
  select /*+ full(emp) parallel(emp,8)*/ * from emp;
  
  分区表效果明显
  
  优化SQL语句排序
  
  排序的操作:
  
  。order by 子句
  。group by 子句
  。select distinct子句
  。创建索引时
  。union或minus
  。排序合并连接
  
  如何避免排序
  
  。添加索引
  。在索引中使用distinct子句
  。避免排序合并连接
  
  使用提示进行调整
  
  使用提示的原则
  
  。语法:/*+ hint */
  。使用表别名:select /*+ index(e dept_idx)*/ * from emp e
  。检验提示
  
  常用的提示
  
  。rule
  。all_rows
  。first_rows
  。use_nl
  。use_hash
  。use_merge
  。index
  。index_asc
  。no_index
  。index_desc(常用于使用max内置函数)
  。index_combine(强制使用位图索引)
  。index_ffs(索引快速完全扫描)
  。use_concat(将查询中所有or条件使用union all)
  。parallel
  。noparallel
  。full
  。ordered(基于成本)
  

某些select 语句中的where子句不使用索引. 这里有一些例子:

1、IS NULL 与 IS NOT NULL
  不能用null作索引,任何包含null值的列都将不会被包含在索引中。即使索引有多列这样的情况下,只要这些列中有一列含有null,该列就会从索引中排除。也就是说如果某列存在空值,即使对该列建索引也不会提高性能。
  任何在where子句中使用is null或is not null的语句优化器是不允许使用索引的。

2、'!=' 将不使用索引. 记住, 索引只能告诉你什么存在于表中, 而不能告诉你什么不存在于表中

不使用索引: select * from employee where salary<>3000;
使用索引: select account_name from transaction where amount >0;
使用索引: select * from employee where salary<3000 or salary>3000;

3、联接列,'||'是字符连接函数. 就象其他函数那样, 停用了索引

不使用索引: select account_name,amount from transaction where account_name||account_type='AMEXA';
使用索引: select account_name,amount from transaction where account_name = 'AMEX' and account_type=' A';

4、'+'是数学函数. 就象其他数学函数那样, 停用了索引

不使用索引: select account_name, amount from transaction where amount + 3000 >5000;
使用索引: select account_name, amount from transaction where amount > 2000 ;

5、相同的索引列不能互相比较,这将会启用全表扫描

不使用索引: select account_name, amount from transaction where account_name = nvl(:acc_name,account_name);
使用索引: select account_name, amount from transaction where account_name like nvl(:acc_name,'%');

6、带通配符(%)的like语句

不使用索引: select * from employee where last_name like '%cliton%';
使用索引: select * from employee where last_name like 'c%'

7、IN和EXISTS

不使用索引: ... where column in(select * from ... where ...);
使用索引: ... where exists (select 'X' from ...where ...);
同时应尽可能使用NOT EXISTS来代替NOT IN,尽管二者都使用了NOT(不能使用索引而降低速度),NOT EXISTS要比NOT IN查询效率更高。

怎样监控无用的索引

Oracle 9i以上,可以监控索引的使用情况,如果一段时间内没有使用的索引,一般就是无用的索引

  语法为:
  开始监控:alter index index_name monitoring usage;
  检查使用状态:select * from v$object_usage;
  停止监控:alter index index_name nomonitoring usage;

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/8541256/viewspace-666079/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/8541256/viewspace-666079/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值