原语句
update HAHA a set (td03_flag) = (select td03_flag
from z_temp1 b where a.user_id = b.user_id and lx = 'pz')Plan hash value: 1855602026
SQL_ID 62h7a9s7yyr18, child number 0
-------------------------------------
update HAHA a set (td03_flag) = (select td03_flag
from z_temp1 b where a.user_id = b.user_id and lx = 'pz')
Plan hash value: 1855602026
-------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | | | 8720M(100)| |
| 1 | UPDATE | HAHA | | | | |
| 2 | TABLE ACCESS FULL | HAHA | 2094K| 51M| 5404 (3)| 00:01:05 |
| 3 | TABLE ACCESS BY INDEX ROWID | Z_TEMP1 | 24383 | 714K| 4163 (2)| 00:00:50 |
| 4 | BITMAP CONVERSION TO ROWIDS | | | | | |
| 5 | BITMAP AND | | | | | |
| 6 | BITMAP CONVERSION FROM ROWIDS| | | | | |
|* 7 | INDEX RANGE SCAN | Z_TEMP1_U | 2438K| | 3 (0)| 00:00:01 |
| 8 | BITMAP CONVERSION FROM ROWIDS| | | | | |
|* 9 | INDEX RANGE SCAN | Z_TEMP1_L | 2438K| | 4108 (2)| 00:00:50 |
-------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
7 - access("B"."USER_ID"=:B1)
9 - access("LX"='pz')
我们可以看第7步的谓词7 - access("B"."USER_ID"=:B1) 这种:B1 是一个变量,变量就有输入源,这里的变量的输入源就是第2步中的每一行
我们就可以简单理解为,就是第2步有多少条语句,第三步就要执行多少次(7是第三步的子步骤,从这一步开始,一直执行完整个 第3步) 这种行为即是Nested loop。
虽然这里有索引,但这里的整个过程,是 两个位图索引 bitmap and,并且会回表,都是单块读,其中回表的单块读在这里占大头(每次都有24383个单块读)的。 我们从统计信息看到 步骤2 有2094K 行
我们可以简单认为, 第三步 这个整个步骤(bitmap and +回表) 被整个执行了 2094K即200多万次。 不慢才怪
优化后语句
explain plan for merge into HAHA a
using (select td03_flag, user_id
from z_temp1 b
where user_id in (select user_id
from HAHA where lx='pz')
) h
on (a.user_id = h.user_id)
when matched then
update set a.td03_flag = h.td03_flag;
这里需要创建两个索引
create index HAHA_IDX on HAHA(lx,user_id) ;
create index z_temp1_ind_uidtd03 on z_temp1(userid,td03_flag) ;
优化前SQL2个小时还没跑完
之后虽然执行时间对方没有反馈,但对方也没有再喊叫 看来满足需求了:)
优化虽易,乙方不易,且行且珍惜