Oracle 通过复合索引提高查询性能的一个真实客户例子

这是一个真实的应用,客户报了一个EBS的performance bug, 在Invoice form里,选择了一个客户后,再打开账单地址(location)的LOV,花了20分钟出来了3条地址数据.


分析了客户上传的trc文件(转成prf),发现查询是类似这样的:


select t1.customer_id, t1.customer_name, t2.location
......
from customer t1, customer_site t2
where t1.customer_number = :P_number
and t1.site_id = t2.customer_site_id
and t2.location like '%%'


在prf中显示,对customer_site表是 INDEX SCAN, 返回了800多万条数据, 再查看了customer_site表定义,发现对存在这样一个index: INDEX_N4 on (location), 这是一个单一索引,感觉使用这个单一索引和全表扫描并没有太大区别,因为是先查找出了800多万条数据,然后再进行外连接,所以效率这么低.


于是想到了用复合索引,因为查询条件中涉及到了两个列(customer_site_id和location),所以把customer_site_id也加入到索引INDEX_N4中,于是索引为这样: 
create index INDEX_N4 on customer_site(location,customer_site_id)
然后再让客户试了一下,查询时间减少到了几秒钟.


在建立这个复合索引的时候,对于这个顺序我纠结了一阵子,索引列的顺序对查询的性能还是有影响的,所以这两列的顺序也要确定一下,网上搜索了一下发现有这样的约定:
1. 选择性最大的列做复合索引的前导列.
2. 查询时where的列能包含索引列.
这两列都在where查询语句中,所以添加customer_site_id到索引中是正确的,而在这里location的选择性比customer_site_id大,所以location放前面.在比较确定做这样的改变能解决客户问题后,我把这个解决方案给了客户,事实上也确实解决了客户的问题.

你可能感兴趣的:(Oracle,oracle,performance)