您的位置:首页 > 数据库

利用ordered hints优化SQL

2014-03-12 13:03 288 查看
SQL_ID 4g70n3k9bqc5v, child number 0

-------------------------------------

MERGE INTO YJBZH_GRXDFHZMXJL GRXDFHZMXJL USING ( SELECT A.AGMT_ID AS

AGMT_ID, B.CUST_NAME AS CUST_NAME FROM DWF.F_AGT_CADB_BOOK_H A,

DWF.F_AGT_SAVB_BASICINFO_H B WHERE A.START_DT <= TO_DATE(:B1

,'yyyy-mm-dd') AND A.END_DT > TO_DATE(:B1 ,'yyyy-mm-dd') AND B.START_DT

<= TO_DATE(:B1 ,'yyyy-mm-dd') AND B.END_DT > TO_DATE(:B1 ,'yyyy-mm-dd')

AND A.MASTER_CARD_NO = B.AGMT_ID ) SAVB_BASICINFO ON (

RTRIM(GRXDFHZMXJL.DFZH) = SAVB_BASICINFO.AGMT_ID AND CJRQ =

TO_CHAR(TO_DATE(:B1 , 'YYYY-MM-DD'),'yyyymmdd') ) WHEN MATCHED THEN

UPDATE SET GRXDFHZMXJL.DFHM = SAVB_BASICINFO.CUST_NAME

Plan hash value: 2923259190

---------------------------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

---------------------------------------------------------------------------------------------------------

| 0 | MERGE STATEMENT | | | | 44331 (100)| |

| 1 | MERGE | YJBZH_GRXDFHZMXJL | | | | |

| 2 | VIEW | | | | | |

| 3 | NESTED LOOPS | | 1 | 1862 | 44331 (1)| 00:08:52 |

| 4 | NESTED LOOPS | | 15 | 1862 | 44331 (1)| 00:08:52 |

| 5 | MERGE JOIN CARTESIAN | | 1 | 1808 | 44313 (1)| 00:08:52 |

|* 6 | TABLE ACCESS FULL | YJBZH_GRXDFHZMXJL | 1 | 1762 | 26057 (1)| 00:05:13 |

| 7 | BUFFER SORT | | 2120K| 93M| 18256 (2)| 00:03:40 |

|* 8 | TABLE ACCESS FULL | F_AGT_SAVB_BASICINFO_H | 2120K| 93M| 18256 (2)| 00:03:40 |

|* 9 | INDEX RANGE SCAN | F_AGT_CADB_BOOK_H_IDX2 | 15 | | 2 (0)| 00:00:01 |

|* 10 | TABLE ACCESS BY INDEX ROWID| F_AGT_CADB_BOOK_H | 1 | 54 | 18 (0)| 00:00:01 |

---------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

6 - filter("CJRQ"=TO_CHAR(TO_DATE(:B1,'YYYY-MM-DD'),'yyyymmdd'))

8 - filter(("B"."START_DT"<=TO_DATE(:B1,'yyyy-mm-dd') AND

"B"."END_DT">TO_DATE(:B1,'yyyy-mm-dd')))

9 - access("A"."AGMT_ID"=RTRIM("GRXDFHZMXJL"."DFZH") AND

"A"."END_DT">TO_DATE(:B1,'yyyy-mm-dd') AND "A"."END_DT" IS NOT NULL)

10 - filter(("A"."MASTER_CARD_NO" IS NOT NULL AND "A"."START_DT"<=TO_DATE(:B1,'yyyy-mm-dd')

AND "A"."MASTER_CARD_NO"="B"."AGMT_ID"))

select count(*) from YJBZH_GRXDFHZMXJL

--0

后来发现多个merge在一个会话里,添加日志后表数据有20W+

select count(*) from dwf.F_AGT_SAVB_BASICINFO_H B where (("B"."START_DT"<=TO_DATE(20131231,'yyyy-mm-dd') AND

"B"."END_DT">TO_DATE(20131231,'yyyy-mm-dd')))

---返回了1071795条记录

那此时ID=5 就傻逼了,实际需要至少返回1071795 然后作为驱动集去驱动ID=9 那么F_AGT_CADB_BOOK_H_IDX2 需要扫描1071795次,此时SQL肯定跑不出来

这时候关联顺序变成了YJBZH_GRXDFHZMXJL和F_AGT_SAVB_BASICINFO_H进行笛卡尔积,产生的结果集在和F_AGT_CADB_BOOK_H进行关联,但是看SQL并不是这样

正确的关联顺序是F_AGT_CADB_BOOK_H和F_AGT_SAVB_BASICINFO_H关联产生的结果集在和YJBZH_GRXDFHZMXJL关联。

添加hints:

ORDERED提示强制Oracle按照From子句中表出现的顺序进行表连接。

通过ORDERED提示,可以避免CBO SQL解析过程中的表连接评估,从而避免Oracle产生错误的执行计划,或者强制Oracle按照我们指定的方式执行。在很多时候,当我们清楚地了解数据结构和数据分布之后,就可以通过ORDERED提示来提高SQL性能。

SQL_ID cw628tpmjcbjv, child number 0

-------------------------------------

MERGE /*+ordered*/ INTO YJBZH_GRXDFHZMXJL GRXDFHZMXJL USING ( SELECT

A.AGMT_ID AS AGMT_ID, B.CUST_NAME AS CUST_NAME FROM

DWF.F_AGT_CADB_BOOK_H A, DWF.F_AGT_SAVB_BASICINFO_H B WHERE A.START_DT

<= TO_DATE(:B1 ,'yyyy-mm-dd') AND A.END_DT > TO_DATE(:B1 ,'yyyy-mm-dd')

AND B.START_DT <= TO_DATE(:B1 ,'yyyy-mm-dd') AND B.END_DT > TO_DATE(:B1

,'yyyy-mm-dd') AND A.MASTER_CARD_NO = B.AGMT_ID ) SAVB_BASICINFO ON (

RTRIM(GRXDFHZMXJL.DFZH) = SAVB_BASICINFO.AGMT_ID AND CJRQ =

TO_CHAR(TO_DATE(:B1 , 'YYYY-MM-DD'),'yyyymmdd') ) WHEN MATCHED THEN

UPDATE SET GRXDFHZMXJL.DFHM = SAVB_BASICINFO.CUST_NAME

Plan hash value: 2400855618

--------------------------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |

--------------------------------------------------------------------------------------------------------

| 0 | MERGE STATEMENT | | | | | 138K(100)| |

| 1 | MERGE | YJBZH_GRXDFHZMXJL | | | | | |

| 2 | VIEW | | | | | | |

|* 3 | HASH JOIN | | 1 | 1862 | | 138K (2)| 00:27:39 |

|* 4 | TABLE ACCESS FULL | YJBZH_GRXDFHZMXJL | 1 | 1762 | | 26057 (1)| 00:05:13 |

|* 5 | HASH JOIN | | 11M| 1074M| 374M| 112K (2)| 00:22:25 |

|* 6 | TABLE ACCESS FULL| F_AGT_CADB_BOOK_H | 5951K| 306M| | 69245 (2)| 00:13:51 |

|* 7 | TABLE ACCESS FULL| F_AGT_SAVB_BASICINFO_H | 2120K| 93M| | 18256 (2)| 00:03:40 |

--------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

3 - access("A"."AGMT_ID"=RTRIM("GRXDFHZMXJL"."DFZH"))

4 - filter("CJRQ"=TO_CHAR(TO_DATE(:B1,'YYYY-MM-DD'),'yyyymmdd'))

5 - access("A"."MASTER_CARD_NO"="B"."AGMT_ID")

6 - filter(("A"."MASTER_CARD_NO" IS NOT NULL AND "A"."START_DT"<=TO_DATE(:B1,'yyyy-mm-dd')

AND "A"."END_DT">TO_DATE(:B1,'yyyy-mm-dd')))

7 - filter(("B"."START_DT"<=TO_DATE(:B1,'yyyy-mm-dd') AND

"B"."END_DT">TO_DATE(:B1,'yyyy-mm-dd')))
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: