首页 > Oracle > 一个简单的sql,优化执行计划中出现的filter!
2014
03-10

一个简单的sql,优化执行计划中出现的filter!

在执行计划中,operation出现filter,这里就需要注意了,需要看一下这个filter是什么filter,是过滤型filter还是相当于NL的filter,这里贴一个关于filter的优化案例。sql经过简单的改写了,不过原始sql和改写的sql差不多。

原始sql就和上面的sql差不多,我们来看一下这个执行计划。

在这个sql中,table3 有200W+的数据,table2有40W+的数据,table1只有4W+的数据。

注意看执行计划中operation中,id=1这里是filter操作,filter操作是通过id=2和id=8连接起来的,这里的filter相当于嵌套循环操作,也就是说id=2这里会当成驱动表,驱动id=8,往执行计划里面看,filter首先要过滤的是table3,而table3是一个200W的大表,通过过滤,然后id=2这一部分CBO预估返回905条数据(这里的预估值只有预估少,没有预估多的情况),因为filter相当于一个嵌套循环,驱动表预估返回905条数据,那么被驱动表就要扫描905次,而被驱动表也是table3,那table3就会被扫描905次,table3又是一个大表,这里就体现出来sql慢的地方了。

原因找到了,就是因为这里的filter不合适,被驱动表太大,扫描体积大,因为sql中有反连接,按照一般思路,因为让这种sql走hash join,但是反连接里面有不等值连接,不能走hash join。所以这里通过修改sql,减少被驱动表的扫描次数,方法就是用with as语句,把大表固化成临时表。

通过修改成with as语句,把table3需要的列通过过滤后固化成临时表,这样就比扫描原表快了几百倍,sql从原来的5个多小时,修改后,只需要12秒就可以完成,效率提升非常大。在这个案例中,需要注意的就是执行计划中的filter,特别是类似于嵌套循环的filter,要注意被驱动表的情况。

最后编辑:
作者:Jerry
一个积极向上的小青年,热衷于分享--Focus on DB,BI,ETL