合并与重建索引:
						
				
		
		
				
						
						
				 
		
				
						    随着对表的不断更新,表中的索引会产生越来越多的存储碎片,要对碎片进行整理有两种方式:重建索引或合并索引。
				
		
		
				
						
						
				 
		
				
						    合并索引:将B树索引中的叶节点存储碎片进行合并。
				
		
		
				
						    ALTER INDEX ind_t COALESCE deallocate unused;
						
						
								
								
						
				
		
		
				
						
								    注:不加deallocate unused则合并后仍保留多于的空间。
						
				
		
		
				
				 
		
				
						    重建索引:即进行重新建立,而且可以修改之前的各种参数。
				
		
		
				
						    ALTER INDEX ind_t REBUILD
				
		
		
				
						    tablespace users
				
		
		
				
						    storage(initial 128k
				
		
		
				
						            next 64k);
				
		
		
				
				 
		
				
						    注:在改变属性时还可以修改REVERSE参数,改为反向,或反向改为正向。
				
		
		
				
				 
		
				
				 
		
				
						    对于分区表,一次只能重建其中的一个分区。
				
		
		
				
						    ALTER INDEX ind_t rebuild
				
		
		
				
						    partition p1;
				
		
		
				
				 
		
				
				 
		
				
						
								监视索引:
						
				
		
		
				
				 
		
				
						    监视索引的使用情况:
				
		
		
				
						     打开:ALTERINDEX INDEX_T5 MONITORINGUSAGE;
				
		
		
				
						     查看:select * from v$object_usage;
				
		
		
				
						     关闭:ALTERINDEX INDEX_T5 NOMONITORINGUSAGE;
				
		
		
				
				 
		
				
						    
						监视索引空间使用:
				
		
		
				
						     分析:ANALYZEINDEX INDEX_T5 VALIDATESTRUCTURE;
				
		
		
				
						     查看:select br_rows,br_blks,lf_rows,del_lf_rows from index_stats;
				
		
		
				
						     说明:BR_ROWS为B树分支数,LF_ROWS为B树叶节点数,DEL_LF_ROWS删除但保存在结构中的节点数。
				
		
		
				
						     注:当30%的叶节点是已经删除的叶节点时,则应该考虑重建和合并索引。
				
		
		
				
				 
		
				
				 
		
				
						删除索引:
				
		
		
				
				 
		
				
						    当一下情况时需要删除索引:
				
		
		
				
						
						
				 
		
				
						
								    1、不再需要的索引;
    2、通过一段时间观察,发现很少使用该索引;
    3、该索引无效,必须在重建之前删除;
    4、该索引包含过多存储碎片,需要在重建之前删除该索引;
    5、索引没有提供所期望的性能改善;
						
				
		
		
				  虽然索引的建立没有限制,但是也不是说建立的越多越好,建立所以需要一下的代价:
		
		
				
						
						
				 
		
				
						
								    1、基础表维护时,系统要同时维护索引;
    2、插入、更新、删除数据时需要同时修改索引;
				
		
		
				
						
								    3、在更改数据时会产生大量db file sequential read锁等待;
				
		
		
				
				 
		
				
						    DROP INDEX ind_t;
				
		
		
				
				 
		
				
				 
		
				
						索引使用的限制情况:
				
		
		
				
				 
		
				
						    限制索引是一些没有经验的开发人员经常犯的错误之一。在SQL中有很多陷阱会使一些索引无法使用。具体有如下情况: 
		
		
				
						
						
				 
		
				
						    1、
						使用不等于操作符(<>、!=)
						
				
		
		
		
		
				
						        下面的查询即使在cust_rating列有一个索引,查询语句仍然执行一次全表扫描。
        select cust_Id,cust_name
        from   customers
        where  cust_rating <> 'aa';
		
		
				
						        把上面的语句改成如下的查询语句,在采用基于规则的优化器而不是基于代价的优化器时,将会使用索引。
        select cust_Id,cust_name
        from   customers
        where  cust_rating < 'aa' or cust_rating > 'aa';
		
		
				
						        
						注:通过把不等于操作符改成OR条件,就可以使用索引,以避免全表扫描。
						
     
    2、使用IS NULL 或IS NOT NULL
		
		
				
						        使用IS NULL 或IS NOT NULL同样会限制索引的使用。因为NULL值并没有被定义。
		
		
				
						        在SQL语句中使用NULL会有很多的麻烦。因此建议开发人员在建表时,把需要索引的列设成NOT NULL。
		
		
				
						        如果被索引的列在某些行中存在NULL值,就不会使用这个索引,除非索引是一个位图索引。
		
		
				
						
						
				 
		
				
						    
						3、使用函数
						
				
		
		
				
						        如果不使用基于函数的索引,那么在SQL语句的WHERE子句中对存在索引的列使用函数时,会使优化器忽略掉这些索引。
        select empno,ename,deptno
        from   emp
        where  trunc(hiredate)='01-MAY-81';
		
		
				
						        把上面的语句改成下面的语句,这样就可以通过索引进行查找。
        select empno,ename,deptno
        from   emp
        where  hiredate<(to_date('01-MAY-81')+0.9999);
		
		
				
				 
		
				
						        使用这个方法也可以屏蔽不想使用的不良索引,例如:
				
		
		
				
						        数值型:在索引字段上加0,例如
        select * from t1 where empno+0 = v_empno;
        字符型:在索引字段上加'',例如
        select * from t1 where type||'' = v_type; 
				
		
		
				
				 
		
				
						
								    
								4、比较不匹配的数据类型
						
				
		
		
				
						
								        比较不匹配的数据类型也是比较难于发现的性能问题之一。
				
		
		
				
						
								        注意下面查询的例子,account_number是一个VARCHAR2类型,在account_number字段上有索引。下面的语句将执行全表扫描。
        select bank_name,address,city,state,zip
        from   banks
        where  account_number = 990354;
				
		
		
				
						
								        Oracle可以自动把where子句变成to_number(account_number)=990354,这样就限制了索引的使用,改成下面的查询就可以使用索引:
        select bank_name,address,city,state,zip
        from   banks
        where  account_number ='990354';
				
		
		
				
						
								        
								注:不匹配的数据类型之间比较会让Oracle自动限制索引的使用,即便对这个查询执行Explain Plan也不能让您明白为什么做了一次“全表扫描”。
						
				
		
		
				
				 
		
				
						
								    5、当使系统数据字典或视图
						
				
		
		
				
						
								        系统的数据字典表都未被分析过,可能导致极差的“执行计划”。但是不要擅自对数据字典表做分析,否则可能导致死锁,或系统性能下降。
						
				
		
		
				
						
						
				 
		
				
						
						
				 
		
				
						
								
										创建索引的规则:
								
						
				
		
		
				
						
								
								
						
				 
		
				
						
								    1、经常检索排序大表中40%或非排序表7%的行,建议建索引;
						
				
		
		
				
						
								    2、为了改善多表关联,索引列用于联结;
						
				
		
		
				
						
								    3、列中的值相对比较唯一;
						
				
		
		
				
						
								    4、
						
				
				
						
								取值范围(大:B树索引,小:位图索引);
						
				
		
		
				
						
								    5、Date型列一般适合基于函数的索引;
						
				
		
		
				
						
								    6、列中有许多空值,不适合建立索引;
						
				
		
		
				
						
						
				 
		
				
						
								    7、建议每张表不超过5个索引;
						
				
		
		
				
						
								
								
						
				 
		
				
						
								    8、经常一起使用多个字段检索记录,组合索引比单索引更有效,把最常用的列放在最前面;
						
				
		
		
				
						
						
				 
		
				
						
								    9、合理设定pctfress,注意:不能给索引指定pctused;
						
				
		
		
				
						
						
				 
		
				
						
						
				 
		
				
						
						
				 
		
				
						
						
				 
		
				
						
								
						
				
				
-The End-