728x90
반응형

- 바인드 캡쳐


1. 목적


- SQL에서 사용하는 SQL을 저장하여, 추후 성능 문제가 발생 하였을 경우 실행계획을 분석 할 목적으로 사용됨.

- 특정 시점에 동일 쿼리가 Slow Performance를 보일 경우, v$sql_bind_capture 뷰를 참조하여 사용된 바인드 변수 값과 SQL Plan을 확인 할 수 있다.


2. 단점


- SQL에서 사용한 모든 바인드 변수가 저장 되지는  않는다.

- 특정 수집 주기(_cursor_bind_capture_interval) 에 따라서 바인드 변수의 값을 저장한다. 

- 특정 크기(_cursor_bind_capture_area_size)를 초과 할 경우 값을 저장하지 못한다.

- where 절에 사용된 bind 변수만이 저장된다.


- 수행 SQL (분포도가 다른 값을 넣고 여러 번 수행하여 바인드 캡쳐가 되게 함) 

SELECT  *
FROM ( SELECT :B1 c1 , empno , ename  , rownum rn
       FROM    BIG_EMP
       WHERE   JOB = :B2 AND sal > :B3) V
WHERE  v.rn < 50   ;

BIG_EMP 테이블의 데이터 분포도

-----------------------
Total : 27,986    Rows
-----------------------
CLERK :	25,987    Rows
PRESIDENT :	1999  Rows
-----------------------


- 캡쳐된 바인드 변수 확인

SELECT sql_id , child_number , position , name , value_string , was_captured
FROM   v$sql_bind_capture
WHERE  sql_id = ( SELECT prev_sql_id
                  FROM v$session
                  WHERE sid = userenv('sid') ) ;

SQL_ID	      CHILD_NUMBER POSITION NAME VALUE_STRING WAS_CAPTURED
------------- ------------ -------- ---- ------------ ------------
fn4m909vh5ncn	   1	      1	    :B1                     NO
fn4m909vh5ncn	   1	      2	    :B2	    PRESIDENT      YES
fn4m909vh5ncn	   1	      3	    :B3	        30000	   YES
fn4m909vh5ncn	   0	      1	    :B1		                NO
fn4m909vh5ncn	   0	      2	    :B2	        CLERK      YES
fn4m909vh5ncn	   0	      3	    :B3	            0	   YES

B1은 WHERE절에 있는 바인드 변수가 아니기 때문에 그 값을 저장하지 못함.


- 실행계획 확인 (child number 0)
  전체 데이터

SELECT *
FROM table(dbms_xplan.display_cursor(
                  'fn4m909vh5ncn',
                                0,
                  'allstats last rows cost bytes +alias +outline +predicate')) ;

PLAN_TABLE_OUTPUT
SQL_ID  fn4m909vh5ncn, child number 0
-------------------------------------
SELECT  * FROM ( SELECT :B1 c1 , empno , ename  , rownum rn        FROM
   BIG_EMP        WHERE   JOB = :B2 AND sal > :B3) V WHERE  v.rn < 50

Plan hash value: 3618790554

--------------------------------------------------------------------------------------------------------------
| Id  | Operation           | Name    | Starts | E-Rows |E-Bytes| Cost (%CPU)| A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |         |      1 |        |       |    72 (100)|     49 |00:00:00.01 |     199 |
|*  1 |  VIEW               |         |      1 |  25987 |    26M|    72   (2)|     49 |00:00:00.01 |     199 |
|   2 |   COUNT             |         |      1 |        |       |            |    213 |00:00:00.01 |     199 |
|*  3 |    TABLE ACCESS FULL| BIG_EMP |      1 |  25987 |   710K|    72   (2)|    213 |00:00:00.01 |     199 |
--------------------------------------------------------------------------------------------------------------

Query Block Name ⁄ Object Alias (identified by operation id):
-------------------------------------------------------------

   1 - SEL$2 ⁄ V@SEL$1
   2 - SEL$2
   3 - SEL$2 ⁄ BIG_EMP@SEL$2

Outline Data
-------------

  ⁄*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('11.2.0.1')
      DB_VERSION('11.2.0.1')
      OPT_PARAM('_optimizer_cost_model' 'cpu')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$2")
      OUTLINE_LEAF(@"SEL$1")
      NO_ACCESS(@"SEL$1" "V"@"SEL$1")
      FULL(@"SEL$2" "BIG_EMP"@"SEL$2")
      END_OUTLINE_DATA
  *⁄

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("V"."RN"<50)
   3 - filter(("JOB"=:B2 AND "SAL">TO_NUMBER(:B3)))


- 실행계획 확인 (child number 1)


SELECT *
FROM table(dbms_xplan.display_cursor(
                  'fn4m909vh5ncn',
                                1,
                  'allstats last rows cost bytes +alias +outline +predicate')) ;

PLAN_TABLE_OUTPUT
SQL_ID  fn4m909vh5ncn, child number 1
-------------------------------------
SELECT  * FROM ( SELECT :B1 c1 , empno , ename  , rownum rn        FROM
   BIG_EMP        WHERE   JOB = :B2 AND sal > :B3) V WHERE  v.rn < 50

Plan hash value: 945252388

------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                     | Name          | Starts | E-Rows |E-Bytes| Cost (%CPU)| A-Rows |   A-Time   | Buffers |
------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |               |      1 |        |       |    30 (100)|     49 |00:00:00.01 |     185 |
|*  1 |  VIEW                         |               |      1 |    185 |   190K|    30   (0)|     49 |00:00:00.01 |     185 |
|   2 |   COUNT                       |               |      1 |        |       |            |    213 |00:00:00.01 |     185 |
|*  3 |    TABLE ACCESS BY INDEX ROWID| BIG_EMP       |      1 |    185 |  5180 |    30   (0)|    213 |00:00:00.01 |     185 |
|*  4 |     INDEX RANGE SCAN          | BIG_EMP_IDX02 |      1 |   1999 |       |     5   (0)|   1999 |00:00:00.01 |       9 |
------------------------------------------------------------------------------------------------------------------------------

Query Block Name ⁄ Object Alias (identified by operation id):
-------------------------------------------------------------

   1 - SEL$2 ⁄ V@SEL$1
   2 - SEL$2
   3 - SEL$2 ⁄ BIG_EMP@SEL$2
   4 - SEL$2 ⁄ BIG_EMP@SEL$2

Outline Data
-------------

  ⁄*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('11.2.0.1')
      DB_VERSION('11.2.0.1')
      OPT_PARAM('_optimizer_cost_model' 'cpu')
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$2")
      OUTLINE_LEAF(@"SEL$1")
      NO_ACCESS(@"SEL$1" "V"@"SEL$1")
      INDEX_RS_ASC(@"SEL$2" "BIG_EMP"@"SEL$2" ("BIG_EMP"."JOB"))
      END_OUTLINE_DATA
  *⁄

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("V"."RN"<50)
   3 - filter("SAL">TO_NUMBER(:B3))
   4 - access("JOB"=:B2)




- 바인드 피킹(peeking)


1.목적


- SQL이 최초 실행시 bind 변수를 포함하고 있을 경우, 해당 바인드 변수에 들어온 값을 참조하여 실행계획을 세움

- _optim_peek_user_binds


2. 단점


- 데이터 skew가 심할 경우 초기 바인드 변수의 값에 따라서 실행 계획이 어떻게 생성되냐에 따라 성능 문제가 발생 할 수 있다.

- _optim_peek_user_binds 파라메터를 false 시키는 것이 권장 사항이 될 정도다

- 단점을 보완하기 위하여 Adaptive Cursor Sharing을 사용하여, 들어오는 변수에 따라서 적절하게 실행 계획을 관리한다 (Child Cursor)




반응형

+ Recent posts