본문 바로가기
[DATABASE] ORACLE/SQL Tuning

TABLE ACCESS 패턴 분석 쿼리

by 기미차니 2023. 1. 18.
반응형

Table Access 패턴을 이용한 SQL 튜닝.

특정 테이블의 엑세스 패턴을 분석하여 인덱스 생성 가이드시 활용 한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
-- ###################################################
-- SQL 액세스 패턴 분석
-- 
-- 특정 테이블을 사용하는 전체 쿼리의 액세스 패턴 분석
-- ###################################################
WITH W_SQL_LIST AS 
(
    -- (1) 대상 테이블을 포함한 SQL_ID 추출
    SELECT DISTINCT SQL_ID 
         , INST_ID
      FROM GV$SQL_PLAN P
     WHERE 1=1
       AND OBJECT_NAME IN (SELECT UPPER(:TNAME) FROM DUAL
                            UNION ALL
                           SELECT INDEX_NAME FROM DBA_INDEXES
                            WHERE TABLE_NAME = UPPER(:TNAME)) 
), 
W_SQL_FACE AS 
(
    -- (2) 추출된 SQL_ID의 성능 정보 추출
    SELECT /*+ LEADING(SP) USE_HASH(SA) */ 
           SA.INST_ID 
         , SA.SQL_ID 
         , SA.VERSION_COUNT 
         , SA.EXECUTIONS 
         , SA.FIRST_LOAD_TIME 
         , SA.DISK_READS 
         , SA.DIRECT_WRITES 
         , SA.BUFFER_GETS 
         , SA.ROWS_PROCESSED 
         , SA.OPTIMIZER_COST 
         , SA.PARSING_SCHEMA_NAME 
         , SA.HASH_VALUE 
         , SA.PLAN_HASH_VALUE 
         , SA.MODULE 
         , SA.CPU_TIME 
         , SA.ELAPSED_TIME 
         , SA.LAST_LOAD_TIME 
         , RANK() OVERPARTITION BY SA.INST_ID, SA.PLAN_HASH_VALUE ORDER BY BUFFER_GETS DESC ) RK
      FROM GV$SQLAREA SA, W_SQL_LIST SP
     WHERE 1=1
       AND SA.SQL_ID  = SP.SQL_ID
       AND SA.INST_ID = SP.INST_ID
--       AND MODULE NOT LIKE 'TOAD%'
--       AND MODULE NOT LIKE 'MAX%'
--       AND MODULE NOT LIKE 'TOAD%'
--       AND MODULE NOT LIKE 'LITE%'
--       AND MODULE NOT LIKE 'LINESTOP%'
--       AND MODULE NOT LIKE 'GOLDEN%'
--       AND MODULE NOT LIKE 'GOLDEN%'
--       AND MODULE NOT LIKE 'ORANGE%'
--       AND PARSING_SCHEMA_NAME LIKE 'GMES20%' 
) ,
W_SQL_PT AS 
(
    -- (3) 추출된 SQL_ID별 성능 정보에 대한 PLAN 정보 추출
    SELECT /*+ USE HASH(P X) */ P.INST_ID 
         , P.SQL_ID 
         , P.PLAN_HASH_VALUE 
         , P.OBJECT_NAME ||' ' ||P.OPERATION ||' ' ||P.OPTIONS AS OPERATION 
         , P.OBJECT_TYPE 
         , P.ID 
         , P.PARENT_ID 
         , P.DEPTH 
         , P.ACCESS_PREDICATES 
         , P.FILTER_PREDICATES 
         , P.CHILD_NUMBER
      FROM GV$SQL_PLAN P
           ( SELECT /*+ NO MERGE USE HASH(P F) */ P.INST_ID 
                  , P.PLAN_HASH_VALUE 
                  , P.OPERATION 
                  , P.OPTIONS 
                  , P.OBJECT_NAME 
                  , P.OBJECT_TYPE 
                  , P.ID 
                  , P.PARENT_ID 
                  , P.DEPTH 
                  , P.ACCESS_PREDICATES 
                  , P.FILTER_PREDICATES 
                  , P.SQL_ID
               FROM GV$SQL_PLAN P, W_SQL_FACE F
              WHERE 1=1
                AND F.RK = 1
                AND F.SQL_ID = P.SQL_ID
                AND OBJECT_NAME IN (SELECT UPPER(:TNAME) FROM DUAL
                                     UNION ALL
                                    SELECT INDEX_NAME FROM DBA_INDEXES WHERE TABLE_NAME = UPPER(:TNAME)) 
           ) X
     WHERE X.INST_ID = P.INST_ID
       AND X.PARENT_ID = P.ID
       AND P.SQL_ID = X.SQL_ID
       AND P.PLAN_HASH_VALUE = X.PLAN_HASH_VALUE
--       AND P.OPERATION = 'HASH JOIN'
     UNION ALL
    SELECT /*+ USE HASH(P F)*/ P.INST_ID 
         , P.SQL_ID 
         , P.PLAN_HASH_VALUE 
         , P.OBJECT_NAME ||' ' ||P.OPERATION ||' ' ||P.OPTIONS AS OPERATION 
         , P.OBJECT_TYPE 
         , P.ID 
         , P.PARENT_ID 
         , P.DEPTH 
         , P.ACCESS_PREDICATES 
         , P.FILTER_PREDICATES 
         , P.CHILD_NUMBER
      FROM GV$SQL_PLAN P, W_SQL_FACE F
     WHERE 1=1
       AND F.RK = 1
       AND F.SQL_ID = P.SQL_ID
       AND OBJECT_NAME IN (SELECT UPPER(:TNAME) FROM DUAL
                            UNION ALL
                           SELECT INDEX_NAME FROM DBA_INDEXES WHERE TABLE_NAME = UPPER(:TNAME)) 
)
SELECT DECODE( SEQ# , 1 , DECODE(INST_CNT , 2 , 3 , 1 , INST_ID)) INST_ID 
     , DECODE( SEQ# , 1 , MODULE ) MODULE 
     , DECODE( SEQ# , 1 , (SELECT KGLFNOBJ FROM SYS.X$KGLCURSOR_CHILD X WHERE X.KGLOBT03 = A.SQL_ID AND ROWNUM <= 1)) TEXT 
     , DECODE( SEQ# , 1 , SQL_ID ) SQL_ID 
     , DECODE( SEQ# , 1 , LITER_CNT ) LITER_CNT 
     , DECODE( SEQ# , 1 , PLAN_HASH_VALUE ) PLAN_HASH_VALUE 
     , DECODE( SEQ# , 1 , PARSING_SCHEMA_NAME ) PARSING_SCHEMA_NAME 
     , DECODE( SEQ# , 1 , EXECUTIONS ) EXEC_T 
     , DECODE( SEQ# , 1 , FACE_EXEC ) FA_EXEC 
     , DECODE( SEQ# , 1 , BUFFER_GETS ) BG 
     , DECODE( SEQ# , 1 , FACE_BGETS ) FA_BG 
     , DECODE( SEQ# , 1 , ROUND(( BUFFER_GETS ) /DECODE(( EXECUTIONS ) , 0 , 1 , ( EXECUTIONS ) ) , 0 )) Buffer_gets
     , DECODE( SEQ# , 1 , ROUND(( DISK_READS ) /DECODE(( EXECUTIONS ) , 0 , 1 , ( EXECUTIONS ) ) , 2 )) Disk_reads 
     , DECODE( SEQ# , 1 , ROUND(( ROWS_PROCESSED ) /DECODE(( EXECUTIONS ) , 0 , 1 , ( EXECUTIONS ) ) , 0 )) Rows_Proc 
     , DECODE( SEQ# , 1 , ROUND((( ELAPSED_TIME ) /DECODE(( EXECUTIONS ) , 0 , 1 , ( EXECUTIONS ) ) ) /1000000 , 3 )) Elapsed 
     , DECODE( SEQ# , 1 , ROUND((( CPU_TIME ) /DECODE(( EXECUTIONS ) , 0 , 1 , ( EXECUTIONS ) ) ) /1000000 , 3 )) CPU_Time 
     , ID 
     , PARENT_ID 
     , SEQ# 
     , OPERATION 
     , FILTER_PREDICATES 
     , ACCESS_PREDICATES
  FROM (SELECT A.* , RANK() OVER (ORDER BY BUFFER_GETS DESC, SQL_ID, PLAN_HASH_VALUE) BG_SEQ#
          FROM (SELECT /*+ LEADING(P) USE HASH(P F S) */ ROW_NUMBER() OVERPARTITION BY X.SQL_ID, X.PLAN_HASH_VALUE ORDER BY X.ID) SEQ#, X.*
                  FROM (SELECT P.ID 
                             , P.PARENT_ID 
                             , P.SQL_ID 
                             , P.PLAN_HASH_VALUE 
                             , SUM( S.LITER_CNT ) LITER_CNT 
                             , MAXP.OPERATION ) OPERATION 
                             , MAXP.FILTER_PREDICATES ) FILTER_PREDICATES 
                             , MAXP.ACCESS_PREDICATES ) ACCESS_PREDICATES 
                             , MAX( F.MODULE ) MODULE 
                             , MAX( F.PARSING_SCHEMA_NAME ) PARSING_SCHEMA_NAME 
                             , MAX( S.EXECUTIONS ) EXECUTIONS 
                             , MAX( F.EXECUTIONS ) FACE_EXEC 
                             , MAX( S.BUFFER_GETS ) BUFFER_GETS 
                             , MAX( F.BUFFER_GETS ) FACE_BGETS 
                             , MAX( S.DISK_READS ) DISK_READS 
                             , MAX( S.ROWS_PROCESSED ) ROWS_PROCESSED 
                             , MAX( S.ELAPSED_TIME ) ELAPSED_TIME 
                             , MAX( S.CPU_TIME ) CPU_TIME 
                             , MAX( F.INST_ID ) INST_ID 
                             , MAXDISTINCT F.INST_ID ) INST_CNT
                          FROM W_SQL_PT P, W_SQL_FACE F,
                               ( SELECT INST_ID --같은 PLAN HASH VALUE 를 같는 쿼리의 일량을 모두 합침 
                                      , COUNTDISTINCT SQL_ID ) LITER_CNT 
                                      , MAX( VERSION_COUNT ) VERSION_COUNT 
                                      , SUM( EXECUTIONS ) EXECUTIONS 
                                      , MIN( FIRST_LOAD_TIME ) FIRST_LOAD_TIME 
                                      , SUM( DISK_READS ) DISK_READS 
                                      , SUM( DIRECT_WRITES ) DIRECT_WRITES 
                                      , SUM( BUFFER_GETS ) BUFFER_GETS 
                                      , SUM( ROWS_PROCESSED ) ROWS_PROCESSED 
                                      , AVG( OPTIMIZER_COST ) OPTIMIZER_COST 
                                      , MAX( PARSING_SCHEMA_NAME ) PARSING_SCHEMA_NAME 
                                      , MAX( HASH_VALUE ) HASH_VALUE 
                                      , PLAN_HASH_VALUE 
                                      , MAXMODULE ) MODULE 
                                      , SUM( CPU_TIME ) CPU_TIME 
                                      , SUM( ELAPSED_TIME ) ELAPSED_TIME 
                                      , MAX( LAST_LOAD_TIME ) LAST_LOAD_TIME
                                   FROM W_SQL_FACE
                                  WHERE 1=1
                                  GROUP BY INST_ID, PLAN_HASH_VALUE ) S
                         WHERE F.RK = 1
                           AND F.PLAN_HASH_VALUE = S.PLAN_HASH_VALUE
                           AND F.INST_ID = S.INST_ID
                           AND F.SQL_ID = P.SQL_ID
                           AND F.INST_ID = P.INST_ID
                         GROUP BY P.IDP.SQL_ID ,P.PARENT_ID ,P.PLAN_HASH_VALUE 
                  ) X 
          ) A 
  ) A
  ORDER BY BG_SEQ# , SEQ# 
;
cs

 

[참조 사이트]

TABLE ACCESS 패턴을 이용한 SQL 튜닝 – DATA ON-AIR (dataonair.or.kr)

 

TABLE ACCESS 패턴을 이용한 SQL 튜닝

TABLE ACCESS 패턴을 이용한 SQL 튜닝 ㈜엑셈 컨설팅본부 /DB컨설팅팀 오 경렬 본 문서는 필자가 사용하는 TABLE ACCESS 패턴을 확인하는 스크립트에 대한 내용입니다. 필자가 SQL 튜닝을 진행하면서 애용

dataonair.or.kr

 

반응형

댓글