有朋友问我一个update语句,下面两种写法哪个性能更高,一个是没HINT的,一个是有HINT的
- UPDATE CS_PERFORMANCE_CURRENT C
- SET C.PERFORMANCE_SCORE = '0.00', C.ASSESS_DESC = '劳动纪律考核'
- WHERE C.TARGET_MODE_SEQ_ID =
- (SELECT D.SEQ_ID
- FROM CS_TARGET_MODEL_REL D, CS_AREA A
- WHERE D.ASSESS_ID = 1265
- AND C.TARGET_MODE_SEQ_ID = D.SEQ_ID
- AND D.STAFF_ID = 8
- AND C.COM_DATE = TO_DATE('20110801','YYYYMMDD')
- AND D.TARGET_MODEL_ID = 332
- AND D.STATE = TO_CHAR(2)
- AND D.AREA_ID = A.AREA_ID
- AND A.AREA_NAME = '永兴支局');
- Plan hash value: 2321634139
- ----------------------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- ----------------------------------------------------------------------------------------------------------
- | 0 | UPDATE STATEMENT | | 1 | 41 | 679 (1)| 00:00:09 |
- | 1 | UPDATE | CS_PERFORMANCE_CURRENT | | | | |
- |* 2 | FILTER | | | | | |
- | 3 | TABLE ACCESS FULL | CS_PERFORMANCE_CURRENT | 124K| 4968K| 664 (1)| 00:00:08 |
- |* 4 | FILTER | | | | | |
- | 5 | NESTED LOOPS | | 1 | 52 | 3 (0)| 00:00:01 |
- |* 6 | TABLE ACCESS BY INDEX ROWID| CS_TARGET_MODEL_REL | 1 | 26 | 2 (0)| 00:00:01 |
- |* 7 | INDEX UNIQUE SCAN | PK_CS_TARGET_RULE_REL | 1 | | 1 (0)| 00:00:01 |
- |* 8 | TABLE ACCESS BY INDEX ROWID| CS_AREA | 1 | 26 | 1 (0)| 00:00:01 |
- |* 9 | INDEX UNIQUE SCAN | PK_CS_AREA_NEW | 1 | | 0 (0)| 00:00:01 |
- ----------------------------------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 2 - filter("C"."TARGET_MODE_SEQ_ID"= (SELECT "D"."SEQ_ID" FROM "CS_AREA"
- "A","CS_TARGET_MODEL_REL" "D" WHERE :B1=TO_DATE(' 2011-08-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss')
- AND "D"."SEQ_ID"=:B2 AND "D"."STAFF_ID"=8 AND "D"."ASSESS_ID"=1265 AND "D"."TARGET_MODEL_ID"=332
- AND "D"."STATE"='2' AND "D"."AREA_ID"="A"."AREA_ID" AND "A"."AREA_NAME"='永兴支局'))
- 4 - filter(:B1=TO_DATE(' 2011-08-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
- 6 - filter("D"."STAFF_ID"=8 AND "D"."ASSESS_ID"=1265 AND "D"."TARGET_MODEL_ID"=332 AND
- "D"."STATE"='2')
- 7 - access("D"."SEQ_ID"=:B1)
- 8 - filter("A"."AREA_NAME"='永兴支局')
- 9 - access("D"."AREA_ID"="A"."AREA_ID")
- 已用时间: 00: 00: 00.29
- 统计信息
- ----------------------------------------------------------
- 1 recursive calls
- 0 db block gets
- 32670 consistent gets
- 21 physical reads
- 0 redo size
- 536 bytes sent via SQL*Net to client
- 978 bytes received via SQL*Net from client
- 3 SQL*Net roundtrips to/from client
- 1 sorts (memory)
- 0 sorts (disk)
- 0 rows processed
- UPDATE /*+ PUSH_SUBQ(@D) */CS_PERFORMANCE_CURRENT C
- SET C.PERFORMANCE_SCORE = '0.00', C.ASSESS_DESC = '劳动纪律考核'
- WHERE C.TARGET_MODE_SEQ_ID =
- (SELECT /*+ QB_NAME(D) */ D.SEQ_ID
- FROM CS_TARGET_MODEL_REL D, CS_AREA A
- WHERE D.ASSESS_ID = 1265
- AND C.TARGET_MODE_SEQ_ID = D.SEQ_ID
- AND D.STAFF_ID = 8
- AND C.COM_DATE = TO_DATE('20110801','YYYYMMDD')
- AND D.TARGET_MODEL_ID = 332
- AND D.STATE = TO_CHAR(2)
- AND D.AREA_ID = A.AREA_ID
- AND A.AREA_NAME = '永兴支局')
- Plan hash value: 4189652906
- ----------------------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- ----------------------------------------------------------------------------------------------------------
- | 0 | UPDATE STATEMENT | | 1 | 39 | 43 (0)| 00:00:01 |
- | 1 | UPDATE | CS_PERFORMANCE_CURRENT | | | | |
- |* 2 | TABLE ACCESS FULL | CS_PERFORMANCE_CURRENT | 1 | 39 | 40 (0)| 00:00:01 |
- |* 3 | FILTER | | | | | |
- | 4 | NESTED LOOPS | | 1 | 47 | 3 (0)| 00:00:01 |
- |* 5 | TABLE ACCESS BY INDEX ROWID| CS_TARGET_MODEL_REL | 1 | 25 | 2 (0)| 00:00:01 |
- |* 6 | INDEX UNIQUE SCAN | PK_CS_TARGET_RULE_REL | 1 | | 1 (0)| 00:00:01 |
- |* 7 | TABLE ACCESS BY INDEX ROWID| CS_AREA | 1 | 22 | 1 (0)| 00:00:01 |
- |* 8 | INDEX UNIQUE SCAN | PK_CS_AREA_NEW | 1 | | 0 (0)| 00:00:01 |
- ----------------------------------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 2 - filter("C"."TARGET_MODE_SEQ_ID"= (SELECT /*+ PUSH_SUBQ QB_NAME ("D") */ "D"."SEQ_ID" FROM
- "CS_AREA" "A","CS_TARGET_MODEL_REL" "D" WHERE :B1=TO_DATE(' 2011-08-01 00:00:00', 'syyyy-mm-dd
- hh24:mi:ss') AND "D"."SEQ_ID"=:B2 AND "D"."ASSESS_ID"=1265 AND "D"."STAFF_ID"=8 AND
- "D"."TARGET_MODEL_ID"=332 AND "D"."STATE"='2' AND "D"."AREA_ID"="A"."AREA_ID" AND
- "A"."AREA_NAME"='永兴支局'))
- 3 - filter(:B1=TO_DATE(' 2011-08-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
- 5 - filter("D"."ASSESS_ID"=1265 AND "D"."STAFF_ID"=8 AND "D"."TARGET_MODEL_ID"=332 AND
- "D"."STATE"='2')
- 6 - access("D"."SEQ_ID"=:B1)
- 7 - filter("A"."AREA_NAME"='永兴支局')
- 8 - access("D"."AREA_ID"="A"."AREA_ID")
- 统计信息
- ----------------------------------------------------------
- 1 recursive calls
- 0 db block gets
- 32670 consistent gets
- 21 physical reads
- 0 redo size
- 536 bytes sent via SQL*Net to client
- 978 bytes received via SQL*Net from client
- 3 SQL*Net roundtrips to/from client
- 1 sorts (memory)
- 0 sorts (disk)
- 0 rows processed
可以看到,逻辑读都是一样的,那么这个SQL,加不加HINT性能都一样。其实对于Oracle中的update 语句,如果SQL很复杂,需要关联多个表去做update,这个时候应该用
merge 语句代替 update,用Merge 改写之后 :
- MERGE INTO CS_PERFORMANCE_CURRENT A
- USING (SELECT D.SEQ_ID
- FROM CS_TARGET_MODEL_REL D,
- CS_AREA M
- WHERE D.ASSESS_ID = 1265 AND
- D.STAFF_ID = 8 AND
- D.TARGET_MODEL_ID = 332 AND
- D.STATE = TO_CHAR(2) AND
- D.AREA_ID = M.AREA_ID AND
- M.AREA_NAME = '永兴支局') H
- ON (A.TARGET_MODE_SEQ_ID = H.SEQ_ID)
- WHEN MATCHED THEN
- UPDATE SET A.PERFORMANCE_SCORE = '0.00', A.ASSESS_DESC = '劳动纪律考核' WHERE A.COM_DATE = TO_DATE('20110801', 'YYYYMMDD');
- ----------------------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- ----------------------------------------------------------------------------------------------------------
- | 0 | MERGE STATEMENT | | 1 | 167 | 750 (1)| 00:00:10 |
- | 1 | MERGE | CS_PERFORMANCE_CURRENT | | | | |
- | 2 | VIEW | | | | | |
- |* 3 | HASH JOIN | | 1 | 210 | 750 (1)| 00:00:10 |
- | 4 | NESTED LOOPS | | 1 | 52 | 85 (2)| 00:00:02 |
- |* 5 | TABLE ACCESS FULL | CS_TARGET_MODEL_REL | 1 | 26 | 84 (2)| 00:00:02 |
- |* 6 | TABLE ACCESS BY INDEX ROWID| CS_AREA | 1 | 26 | 1 (0)| 00:00:01 |
- |* 7 | INDEX UNIQUE SCAN | PK_CS_AREA_NEW | 1 | | 0 (0)| 00:00:01 |
- | 8 | TABLE ACCESS FULL | CS_PERFORMANCE_CURRENT | 124K| 18M| 664 (1)| 00:00:08 |
- ----------------------------------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 3 - access("A"."TARGET_MODE_SEQ_ID"="D"."SEQ_ID")
- 5 - filter("D"."STAFF_ID"=8 AND "D"."ASSESS_ID"=1265 AND "D"."TARGET_MODEL_ID"=332 AND
- "D"."STATE"='2')
- 6 - filter("M"."AREA_NAME"='永兴支局')
- 7 - access("D"."AREA_ID"="M"."AREA_ID")
- 统计信息
- ----------------------------------------------------------
- 333 recursive calls
- 0 db block gets
- 3474 consistent gets
- 3 physical reads
- 0 redo size
- 546 bytes sent via SQL*Net to client
- 998 bytes received via SQL*Net from client
- 3 SQL*Net roundtrips to/from client
- 15 sorts (memory)
- 0 sorts (disk)
- 0 rows processed
逻辑读下降了近10倍,这里 CS_PERFORMANCE_CURRENT 是全表扫描,它有100W的数据量,所以建立索引在TARGET_MODE_SEQ_ID列上
- Plan hash value: 3908453434
- -----------------------------------------------------------------------------------------------------------
- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
- -----------------------------------------------------------------------------------------------------------
- | 0 | MERGE STATEMENT | | 1 | 167 | 88 (2)| 00:00:02 |
- | 1 | MERGE | CS_PERFORMANCE_CURRENT | | | | |
- | 2 | VIEW | | | | | |
- | 3 | TABLE ACCESS BY INDEX ROWID | CS_PERFORMANCE_CURRENT | 1 | 158 | 3 (0)| 00:00:01 |
- | 4 | NESTED LOOPS | | 1 | 210 | 88 (2)| 00:00:02 |
- | 5 | NESTED LOOPS | | 1 | 52 | 85 (2)| 00:00:02 |
- |* 6 | TABLE ACCESS FULL | CS_TARGET_MODEL_REL | 1 | 26 | 84 (2)| 00:00:02 |
- |* 7 | TABLE ACCESS BY INDEX ROWID| CS_AREA | 1 | 26 | 1 (0)| 00:00:01 |
- |* 8 | INDEX UNIQUE SCAN | PK_CS_AREA_NEW | 1 | | 0 (0)| 00:00:01 |
- |* 9 | INDEX RANGE SCAN | IDX_CS_PFC_CURRENT | 1 | | 1 (0)| 00:00:01 |
- -----------------------------------------------------------------------------------------------------------
- Predicate Information (identified by operation id):
- ---------------------------------------------------
- 6 - filter("D"."STAFF_ID"=8 AND "D"."ASSESS_ID"=1265 AND "D"."TARGET_MODEL_ID"=332 AND
- "D"."STATE"='2')
- 7 - filter("M"."AREA_NAME"='永兴支局')
- 8 - access("D"."AREA_ID"="M"."AREA_ID")
- 9 - access("A"."TARGET_MODE_SEQ_ID"="D"."SEQ_ID")
- 已用时间: 00: 00: 00.18
- 统计信息
- ----------------------------------------------------------
- 0 recursive calls
- 0 db block gets
- 386 consistent gets
- 0 physical reads
- 0 redo size
- 544 bytes sent via SQL*Net to client
- 998 bytes received via SQL*Net from client
- 3 SQL*Net roundtrips to/from client
- 1 sorts (memory)
- 0 sorts (disk)
- 0 rows processed
现在逻辑读降低到386
在Oracle当中,强烈建议 =使用 merge 代替 update语句
转载:http://blog.csdn.net/robinson1988/article/details/7042543#comments