这几天测试java内存数据库,和oracle比较时发下一个update from语句很慢,以下:java
update business_new set fare1_balance_ratio = (select BALANCE_RATIO from bfare2 where bfare2.exchange_type = business_new.exchange_type and bfare2.stock_type = business_new.stock_type and (bfare2.entrust_way = business_new.entrust_way) and (bfare2.entrust_type = business_new.entrust_type) and bfare2.fare_type = '0')
执行计划是这样的:数据库
从执行计划能够看出,走的就是nl关联,因此慢是正常的。oracle
因而将其改写为merge,以下:性能
merge into business_new using bfare2 on (bfare2.exchange_type = business_new.exchange_type and bfare2.stock_type = business_new.stock_type and (bfare2.entrust_way = business_new.entrust_way) and (bfare2.entrust_type = business_new.entrust_type) and bfare2.fare_type = '4') when matched then update set business_new.farex_balance_ratio = bfare2.BALANCE_RATIO
改写后执行计划以下:测试
很快就跑出来了。须要注意的是,update语句自己是经过hint让两表强制走hash join的。spa
除了用merge改写让两表关联走hash join外,还有一种更优、但有条件的作法。以下:code
update (select fare1_balance_ratio,BALANCE_RATIO from business_new,bfare2 where bfare2.exchange_type = business_new.exchange_type and bfare2.stock_type = business_new.stock_type and (bfare2.entrust_way = business_new.entrust_way) and (bfare2.entrust_type = business_new.entrust_type) and bfare2.fare_type = '0') set fare1_balance_ratio = BALANCE_RATIO ;
这也称为inline view更新法,性能是最好的,但相比merge并不明显。但表B的主键必定要在where条件中,而且是以“=”来关联被更新表,不然会遇到ORA-01779: 没法修改与非键值保存表对应的列。形成这个错误的缘由是更新的列不是事实表的列,而是维度表的列。换句话说,若是两张表关联,其中一张表的关联列是主键,那么另外一张表就是事实表,也就是说另外一张表中的列就是可更新的;除非另外一张表的关联列也是主键,不然这张表就是不可更新的,若是更新语句涉及到了这张表,就会出现ORA-1799错误。也就是,要么两张表都经过PK关联,要么只有非PK这张表可更新。blog
至于for循环,乖乖,除非逻辑特别复杂,用for bulk collect,不然不要考虑。内存