Oracle SQL Tuning
这个是大部分想到优化的时候,想到的点,其实片面了。
最好的策略是,先把数据库结构优化好了,再来做SQL Tuning ,这样效果更加明显。
SQL Tuning之前,明白几件事:
(1). 解析
(2). 执行计划
(3). 表连接
(4). Hint
(5). 全表扫描 局部扫描
这里说多了没有意思,贴几个SQL出来,里面包含了Hint 、表扫描 ,给出相应的执行计划。
有Hint:
SELECT /*+ USE_HASH(B,C) */ c.uuid,
c.c_name
FROM gsims.b_contract c,
gsims.b_unitmessage b
WHERE c.c_codeid = b.uuid
AND b.unitcode = '76213161-3'
AND C.D_DATE_INK >= TO_DATE('20101020', 'yyyymmdd')
AND TO_CHAR(C.D_DATE_INK, 'yyyymmdd') <= '20101120'
相应的执行计划
Plan
SELECT STATEMENT FIRST_ROWS Cost : 130 Bytes : 53 Cardinality : 1
5 HASH JOIN "C"."C_CODEID"="B"."UUID" Cost : 130 Bytes : 53 Cardinality : 1
2 TABLE ACCESS BY INDEX ROWID GSIMS.B_UNITMESSAGE Cost : 1 Bytes : 17 Cardinality : 1
1 INDEX UNIQUE SCAN GSIMS.IDX_UNITCODE "B"."UNITCODE"='76213161-3' Cost : 1 Cardinality : 1
4 TABLE ACCESS BY INDEX ROWID GSIMS.B_CONTRACT Cost : 128 Bytes : 6,660 Cardinality : 185
3 INDEX RANGE SCAN GSIMS.INDEX_ORDER_DATE "C"."D_DATE_INK">=TO_DATE('2010-10-20 00:00:00', 'yyyy-mm-dd hh24:mi:ss') TO_CHAR(INTERNAL_FUNCTION("C"."D_DATE_INK"),'yyyymmdd')<='20101120' Cost : 38 Cardinality : 185
无 Hint :
SELECT c.uuid,
c.c_name
FROM gsims.b_contract c,
gsims.b_unitmessage b
WHERE c.c_codeid = b.uuid
AND b.unitcode = '76213161-3'
AND TO_CHAR(C.D_DATE_INK, 'yyyymmdd') BETWEEN '20101020' AND '20101120'
相应的执行计划:
Plan
SELECT STATEMENT FIRST_ROWS Cost : 9 Bytes : 53 Cardinality : 1
5 NESTED LOOPS Cost : 9 Bytes : 53 Cardinality : 1
2 TABLE ACCESS BY INDEX ROWID GSIMS.B_UNITMESSAGE Cost : 1 Bytes : 17 Cardinality : 1
1 INDEX UNIQUE SCAN GSIMS.IDX_UNITCODE "B"."UNITCODE"='76213161-3' Cost : 1 Cardinality : 1
4 TABLE ACCESS BY INDEX ROWID GSIMS.B_CONTRACT TO_CHAR(INTERNAL_FUNCTION("C"."D_DATE_INK"),'yyyymmdd')<='20101120' AND TO_CHAR(INTERNAL_FUNCTION("C"."D_DATE_INK"),'yyyymmdd')>='20101020' Cost : 8 Bytes : 36 Cardinality : 1
3 INDEX RANGE SCAN GSIMS.INDEX_CONTRACT_UNITUUID "C"."C_CODEID"="B"."UUID" Cost : 1 Cardinality : 20
这个是大部分想到优化的时候,想到的点,其实片面了。
最好的策略是,先把数据库结构优化好了,再来做SQL Tuning ,这样效果更加明显。
SQL Tuning之前,明白几件事:
(1). 解析
(2). 执行计划
(3). 表连接
(4). Hint
(5). 全表扫描 局部扫描
这里说多了没有意思,贴几个SQL出来,里面包含了Hint 、表扫描 ,给出相应的执行计划。
有Hint:
SELECT /*+ USE_HASH(B,C) */ c.uuid,
c.c_name
FROM gsims.b_contract c,
gsims.b_unitmessage b
WHERE c.c_codeid = b.uuid
AND b.unitcode = '76213161-3'
AND C.D_DATE_INK >= TO_DATE('20101020', 'yyyymmdd')
AND TO_CHAR(C.D_DATE_INK, 'yyyymmdd') <= '20101120'
相应的执行计划
Plan
SELECT STATEMENT FIRST_ROWS Cost : 130 Bytes : 53 Cardinality : 1
5 HASH JOIN "C"."C_CODEID"="B"."UUID" Cost : 130 Bytes : 53 Cardinality : 1
2 TABLE ACCESS BY INDEX ROWID GSIMS.B_UNITMESSAGE Cost : 1 Bytes : 17 Cardinality : 1
1 INDEX UNIQUE SCAN GSIMS.IDX_UNITCODE "B"."UNITCODE"='76213161-3' Cost : 1 Cardinality : 1
4 TABLE ACCESS BY INDEX ROWID GSIMS.B_CONTRACT Cost : 128 Bytes : 6,660 Cardinality : 185
3 INDEX RANGE SCAN GSIMS.INDEX_ORDER_DATE "C"."D_DATE_INK">=TO_DATE('2010-10-20 00:00:00', 'yyyy-mm-dd hh24:mi:ss') TO_CHAR(INTERNAL_FUNCTION("C"."D_DATE_INK"),'yyyymmdd')<='20101120' Cost : 38 Cardinality : 185
无 Hint :
SELECT c.uuid,
c.c_name
FROM gsims.b_contract c,
gsims.b_unitmessage b
WHERE c.c_codeid = b.uuid
AND b.unitcode = '76213161-3'
AND TO_CHAR(C.D_DATE_INK, 'yyyymmdd') BETWEEN '20101020' AND '20101120'
相应的执行计划:
Plan
SELECT STATEMENT FIRST_ROWS Cost : 9 Bytes : 53 Cardinality : 1
5 NESTED LOOPS Cost : 9 Bytes : 53 Cardinality : 1
2 TABLE ACCESS BY INDEX ROWID GSIMS.B_UNITMESSAGE Cost : 1 Bytes : 17 Cardinality : 1
1 INDEX UNIQUE SCAN GSIMS.IDX_UNITCODE "B"."UNITCODE"='76213161-3' Cost : 1 Cardinality : 1
4 TABLE ACCESS BY INDEX ROWID GSIMS.B_CONTRACT TO_CHAR(INTERNAL_FUNCTION("C"."D_DATE_INK"),'yyyymmdd')<='20101120' AND TO_CHAR(INTERNAL_FUNCTION("C"."D_DATE_INK"),'yyyymmdd')>='20101020' Cost : 8 Bytes : 36 Cardinality : 1
3 INDEX RANGE SCAN GSIMS.INDEX_CONTRACT_UNITUUID "C"."C_CODEID"="B"."UUID" Cost : 1 Cardinality : 20