2014-10-04 BaoXinjian
一、摘要
PLSQL_性能优化系列14_Oracle Index Anaylsis
1. 索引质量
索引质量的高低对数据库整体性能有着直接的影响。
良好高质量的索引使得数据库性能得以数量级别的提升,而低效冗余的索引则使得数据库性能缓慢如牛,即便是使用高档的硬件配置。
因此对于索引在设计之初需要经过反复的测试与考量。
那对于已经置于生产环境中的数据库,我们也可以通过查询相关数据字典得到索引的质量的高低,通过这个分析来指导如何改善索引的性能。
2. 索引创建的基本指导原则
索引的创建应遵循精而少的原则
收集表上所有查询的各种不同组合,找出具有最佳离散度的列(或主键列等)创建单索引
对于频繁读取而缺乏比较理想离散值的列为其创建组合索引
对于组合索引应考虑下列因素来制定合理的索引列顺序,以下优先级别由高到低来作为索引的前导列,第二列等等
- 列被使用的频率
- 该列是否经常使用“ = ”作为常用查询条件
- 列上的离散度
- 组合列经常按何种顺序排序
- 哪些列会作为附件性列被添加
二、案例 - 表上索引和索引质量
1. 查询单表上索引列的相关信息
SQL> @/home/oracle/sql/idx_info.sql Enter value for owner: SH Enter value for table_name: SALES Table Index CL_NAM CL_POS STATUS IDX_TYP DSCD ------------------------- ------------------------- -------------------- ------ -------- --------------- ---- SALES SALES_CHANNEL_BIX CHANNEL_ID 1 N/A BITMAP ASC SALES_CUST_BIX CUST_ID 1 N/A BITMAP ASC SALES_PROD_BIX PROD_ID 1 N/A BITMAP ASC SALES_PROMO_BIX PROMO_ID 1 N/A BITMAP ASC SALES_TIME_BIX TIME_ID 1 N/A BITMAP ASC 5 rows selected.
(1). 从上面的查询结果可知,当前表TRADE_CLIENT_TBL上含有4个索引,应该来说该表索引存在一定冗余。
(2). 大多数情况下,单表上6-7个索引是比较理想的。过多的索引导致过大的资源开销,以及降低DML性能。
2. 获取指定schema或表上的索引质量信息报告
SQL> @/home/oracle/sql/idx_quality.sql Enter value for input_owner: SH Enter value for input_tbname: SALES Table Table Index Data Blks Leaf Blks Clust Index Table Rows Blocks Index Size MB per Key per Key Factor Quality ------------------------- ------------ ---------- ------------------------- ------- --------- --------- ------------ ------------- SALES 918,843 1769 SALES_PROD_BIX 0 14 1 1,074 5-Excellent SALES_CUST_BIX 0 5 1 35,808 5-Excellent SALES_TIME_BIX 0 1 1 1,460 5-Excellent SALES_CHANNEL_BIX 0 23 11 92 5-Excellent SALES_PROMO_BIX 0 13 7 54 5-Excellent 5 rows selected.
(1). 从上面的单表输出的索引质量可知,出现了4个处于Poor级别的索引,也就是说这些个索引具有较大的聚簇因子,几乎接近于表上的行了
(2). 对于这几个索引的质量还应结合该索引的使用频率来考量该索引存在的必要性
(3). 对于聚簇因子,只能通过重新组织表上的数据来,以及调整相应索引列的顺序得以改善
三、案例 - 索引的使用频率报告
Oracle提供了索引监控特性来判断索引是否被使用。在Oracle 10g中,收集统计信息会使得索引被监控,在Oracle 11g中该现象不复存在。
尽管如此,该方式仅提供的是索引是否被使用。索引被使用的频率未能得以体现。
下面的脚本将得到索引的使用率,可以很好的度量索引的使用情况以及根据这个值来判断当前的这些索引是否可以被移除或改进。\
参考了沙弥大神
1. 判断索引是否被使用
SQL> @/home/oracle/sql/idx_usage_detail.sql SH 1 Index Table name Index name Index type Size MB Index operation Executions ------------------------------ ------------------------------ --------------- ----------- --------------------- ---------- COSTS COSTS_PROD_BIX BITMAP 1.75 - 0 COSTS_TIME_BIX BITMAP 1.75 - 0 ****************************** ****************************** *************** ----------- ---------- sum 3.50 0 SALES SALES_CHANNEL_BIX BITMAP 1.75 - 0 SALES_CUST_BIX BITMAP 5.69 SINGLE VALUE 2 FAST FULL SCAN 1 SALES_PROD_BIX BITMAP 1.75 SINGLE VALUE 3 FAST FULL SCAN 1 SALES_PROMO_BIX BITMAP 1.75 FULL SCAN 1 SALES_TIME_BIX BITMAP 1.94 - 0 ****************************** ****************************** *************** ----------- ---------- sum 20.31 8 9 rows selected.
(1). 上面的结果列出了当前数据库中schema为SH且索引大小大于1MB的索引的使用频率。
(2). 由于当前的数据库为标准版,没有分区表功能,所以可以看到很多arc结尾的表,且索引很大,如ACC_POS_STOCK_TBL_ARC上索引达到19G。
(3). 表SALES的主键SALES_PROD_BIX上范围扫描最多,总计被使用次数为3次。
(4). 对于上述列出的被使用的次数为0的那些索引,应考虑索引的设置是否合理。
(5). 过大的索引应考虑能否使用索引压缩。
(6). 最后列出的是报告的schema名称以及索引大小的过滤条件、索引被收集的日期。注,索引列的大小sum求和有些不准确。
2. 总结
本使用了2个替代变量,一个是schema,一个是索引的大小。
缺省情况下,对于那些较小 的索引以及仅仅运行一至两次的sql语句的历史执行计划不会被收集到DBA_HIST_SQL_PLAN。
因此执行脚本时索引大小输入的建议值是100。
如果需要收集所有的历史sql执行计划来判断索引是否被使用,需要修改statistics_level为all或者修改snapshot的收集策略。
收集策略对系统性能有一定的影响,以及耗用大量磁盘空间,因此Prod环境应慎用(UAT和DEV则无妨)。
脚本下载 (由了沙弥大神整理,借用下)
1. idx_info.sql http://files.cnblogs.com/eastsea/idx_info.zip
2. idx_quality.sql http://files.cnblogs.com/eastsea/idx_quality.zip
3. idx_usage_detail.sql http://files.cnblogs.com/eastsea/idx_usage_detail.zip
参考:了沙弥大神 http://blog.csdn.net/leshami/article/details/23687137