如何提高oracle数据库性能 (oracle数据库语句优化)

概述

It is very easy for us to implement sql tuning by toad. We need to do is just give complex sql statement to toad.

相信很多朋友都会碰到那些几十行几百行的sql,像这种复杂的sql单单去做分析都很耗费我们的时间了,有没有一种办法可以一键优化这种复杂的sql语句呢?今天主要分享一下怎么通过toad工具去优化那些复杂的sql,目的是帮助我们减少优化的时间。

原始sql

SELECT mm.inst_id,
 mm.sid,
 mm.TYPE,
 mm.id1,
 mm.id2,
 LPAD (TRUNC (mm.ctime / 60 / 60), 3)
 || ’ Hour ’
 || LPAD (
 TO_CHAR (
 TRUNC (mm.ctime / 60) - TRUNC (mm.ctime / 60 / 60) * 60,
 ’fm09’),
 2)
 || ’ Min ’
 || LPAD (TO_CHAR (mm.ctime - TRUNC (mm.ctime / 60) * 60, ’fm09’), 2)
 || ’ Sec’
 ctime,
 CASE
 WHEN mm.block = 1 AND mm.lmode != 0 THEN ’holder’
 WHEN mm.block = 0 AND mm.request != 0 THEN ’waiter’
 ELSE NULL
 END
 role,
 CASE
 WHEN ee.blocking_session IS NOT NULL
 THEN
 ’waiting for SID ’ || ee.blocking_session
 ELSE
 NULL
 END
 blocking_session,
 dd.sql_text sql_text,
 cc.event wait_event
 FROM gv$lock mm,
 gv$session ee,
 gv$sqlarea dd,
 gv$session_wait cc
 WHERE mm.sid IN
 (SELECT nn.sid
 FROM (SELECT tt.*,
 COUNT (1)
 OVER (PARTITION BY tt.TYPE, tt.id1, tt.id2)
 cnt,
 MAX (tt.lmode)
 OVER (PARTITION BY tt.TYPE, tt.id1, tt.id2)
 lmod_flag,
 MAX (tt.request)
 OVER (PARTITION BY tt.TYPE, tt.id1, tt.id2)
 request_flag
 FROM gv$lock tt) nn
 WHERE nn.cnt > 1
 AND nn.lmod_flag != 0
 AND nn.request_flag != 0)
 AND mm.sid = ee.sid(+)
 AND ee.sql_id = dd.sql_id(+)
 AND mm.sid = cc.sid(+)
 AND ( (mm.block = 1 AND mm.lmode != 0)
 OR (mm.block = 0 AND mm.request != 0))
ORDER BY mm.TYPE,
 mm.id1,
 mm.id2,
 mm.lmode DESC,
 mm.ctime DESC

1、Get execution plan

Editor --> Explain plan current SQL or CTRL + E

oracle亿级数据sql优化通用步骤,oracle数据库sql调优

可以看到执行计划如下:

oracle亿级数据sql优化通用步骤,oracle数据库sql调优

2、 Get statistics/Auto Trace

开启自动trace跟踪:

oracle亿级数据sql优化通用步骤,oracle数据库sql调优

或者在sql编辑区右键选择去开启自动跟踪:

oracle亿级数据sql优化通用步骤,oracle数据库sql调优

3、Get statistics after executed sql.

点击执行后可以看到sql相关统计信息:

oracle亿级数据sql优化通用步骤,oracle数据库sql调优

4、 Tuning SQL

选择自动优化sql:

oracle亿级数据sql优化通用步骤,oracle数据库sql调优

执行sql:

oracle亿级数据sql优化通用步骤,oracle数据库sql调优

可以看到正在自动优化:

oracle亿级数据sql优化通用步骤,oracle数据库sql调优

优化完成后如下:

oracle亿级数据sql优化通用步骤,oracle数据库sql调优

5、 Compare result

这里我们可以看到其中一条sql从3.7秒优化到0.04秒

oracle亿级数据sql优化通用步骤,oracle数据库sql调优

最终sql

SELECT /*+ NO_CPU_COSTING */ mm.inst_id, 
 mm.sid, 
 mm.TYPE, 
 mm.id1, 
 mm.id2, 
 LPAD(TRUNC(mm.ctime / 60 / 60), 3) || ’ Hour ’ || LPAD(TO_CHAR(TRUNC(mm.ctime / 60) - TRUNC(mm.ctime / 60 / 60) * 60, ’fm09’), 2) || ’ Min ’ || LPAD(TO_CHAR(mm.ctime - TRUNC(mm.ctime / 60) * 60, ’fm09’), 2) || ’ Sec’ ctime, 
 CASE WHEN mm.block = 1 
 AND mm.lmode != 0 THEN ’holder’ 
 WHEN mm.block = 0 
 AND mm.request != 0 THEN ’waiter’ 
 ELSE NULL END role, 
 CASE WHEN ee.blocking_session IS NOT NULL THEN ’waiting for SID ’ || ee.blocking_session 
 ELSE NULL END blocking_session, 
 dd.sql_text sql_text, 
 cc.event wait_event 
 FROM gv$lock mm, 
 gv$session ee, 
 gv$sqlarea dd, 
 gv$session_wait cc 
 WHERE EXISTS (SELECT ’X’ 
 FROM (SELECT tt.*, 
 COUNT(1) OVER (PARTITION BY tt.TYPE, 
 tt.id1, 
 tt.id2) cnt, MAX(tt.lmode) OVER (PARTITION BY tt.TYPE, 
 tt.id1, 
 tt.id2) lmod_flag, MAX(tt.request) OVER (PARTITION BY tt.TYPE, 
 tt.id1, 
 tt.id2) request_flag 
 FROM gv$lock tt) nn 
 WHERE nn.cnt > 1 
 AND nn.lmod_flag != 0 
 AND nn.request_flag != 0 
 AND nn.sid = mm.sid) 
 AND mm.sid = ee.sid (+) 
 AND ee.sql_id = dd.sql_id (+) 
 AND mm.sid = cc.sid (+) 
 AND (mm.block = 1 
 AND mm.lmode <> 0 
 OR mm.block = 0 
 AND mm.request <> 0) 
 ORDER BY mm.TYPE, mm.id1, mm.id2, mm.lmode DESC, 
 mm.ctime DESC

虽然花上一些时间我们也可以优化到我们想要的结果,但是通过工具去帮助我们减少这些时间,何乐而不为呢?

觉得有用的朋友多帮忙转发哦!后面会分享更多devops和DBA方面的内容,感兴趣的朋友可以关注下~

oracle亿级数据sql优化通用步骤,oracle数据库sql调优