SQL 힌트의 사용 방법
●  DBA는 특정데이터에 대하여 optimizer가 알 수 없는 정보를 가질 수 있음.
●  DBA는 optimizer보다 더 좋은 execution plan을 선택할 수 있음.
●  DBA는 힌트를 사용하여 강제적으로 사용자가 선택한 execution plan을 생성하도록  optimizer에게 지시가능.

 

힌트의 사용
  힌트의 사용범위
―  SQL문을 위한 Optimization approach―  SQL문에 대한 Cost-based approach의 goal(best throughput, best response time)―  SQL문에 의해 접근되는 table에 대한 access path―  join문에 대한 join순서

―  join문을 처리하기 위한 join operation

 

  Statement Block

―  간단한 SELECT , UPDATE, DELETE SQL문
―  한 parent SQL문나 complex SQL문  내의 subquery
―  한 compound query중의 한 부분

· UNION operator에 의해 조합된 두 개의 component query로 구성한 한 compound query는 두 개의 SQL문 block을 가짐. (각 component query를 위해 하나의 SQL문 block이 생김.)
· 첫 번째 component query에 있는 힌트는 첫 번째 component의 optimizer에만 적용
· 두 번째 component query에 대한 optimizer에는 적용되지 않는다.

●  힌트를 포함하는

Syntax

·DELETE,
SELECT , UPDATE : SQL
문 block을 시작하는 DELETE,
SELECT , UPDATE 키워드입니다. 힌트를 포함하는 comments는  이 키워드들이 나타난 후에 써야합니다.

 

·+ : 오라클이 그 comment를 해석할 수 있게 해주는 기능을합니다. 이 ‘ + ‘는 comment 표시후에 빈칸(blank)이 없이 즉시 따라와야만 합니다.

 

·힌트 : 이절에서언급되는 힌트중의 하나입니다. 만약 comment가 여러 힌트를 가진다면그 힌트들은 최소한 하나의 공간으로서 분리되어 있어야만 합니다.

 

·text : 힌트에 대한 설명

  힌트를 무시하는 경우
―  힌트가 쓰인 comment가 DELETE,
SELECT , UPDATE 키워드 뒤에 오지 않고, 다른 곳에 쓰여 있는경우
―  힌트가 Syntax error를 가진 경우 (동일한 comment내에 error를 가지지 않고 올바로 표현된 다른 힌트들은 인정)
―  충돌한 힌트의 조합들은 무시(한 comment내에 두 개 이상의 힌트가 있을 경우, Optimizer가 어떤 힌트를 먼저 써야하는지 모르는 경우)(동일한 comment내에 충돌한 힌트외에 다른 힌트는 인정.)
· 오라클은 SQL*Forms Version 3 Trigger 와 같은 PL/SQL Version 1 을 사용하는 환경에서는모든 SQL 문에 있는 힌트들을 무시.· Optimizer는 cost-based approach를 사용하는 경우에 힌트를인식.

· 한 SQL문 block에 RULE 힌트를 제외한 어떤 힌트들이 포함되어 있으면, optimizer 는 자동적으로 cost-based approach를 사용.

옵티마이저를 위한 힌트와 사용 목표
―  힌트는 cost-based approach와 rule-based optimization approach 중에 하나를 선택

―  cost-based approach를 선택한 경우에는 best throughput와 best reponse time사이에 하나를 선택

―  SQL문이 optimization approach 와 goal을 기술한 한개의 힌트를 가진다면, optimizer는 statistics의 존재여부와 ALTER SESSSION명령에 있는 OPTIMIZER_GOAL와 OPIMIZER_MODE 초기 파라메타의 값과는 상관없이 기술된 approach를 사용.

 

∮ ALL_ROWS
―  ALL_ROWS 힌트는 best throughput(minimum total resource consumption)을 목적으로 SQL문 block을 최적화하기 위해 cost-based approach를 선택
―  optimizer는 best throughput을 목적으로 SQL문를 최적화
SELECT  
/*+ ALL_ROWS */ empno, ename, sal, job  FROM emp WHERE empno = 566;

 

∮ FIRST_ROWS
―  FIRST_ROWS 힌트는 best response time을 목적으로 SQL문 block을 최적화하기 위해 cost-based approach를 선택.(minimum resource usage to return first row)
―  이 힌트는 아래 내용을 이행할 수 있는 optimizer를 생성
· Index scan을 쓸수 있다면, optimizer는 full table scan보다는 Index scan을 사용.
· Index scan을 쓸수 있다면, optimizer는 연관된 table이 nested loop의 inner table일 때마다, sort-merge join보다는 nested loops join을 선택.
· Index scan이 ORDER BY절에 의해 쓰여지면, optimizer는 sort operation을 피하기 위해 index scan을 선택.
―  optimizer는 best response time을 목적으로 아래 SQL문를 최적화
SELECT  
/*+ FIRST_ROWS */ empno, ename, sal, job FROM emp WHERE empno = 566;
―  Optimizer는 아래 Syntax를 가지는 DELETE와 UPDATE SQL문 blocks과SELECT SQL문 block 에 있는 힌트는 무시.· set operators(UNION, INTERSECT, MINUS, UNION ALL) · GROUP BY·FOR UPDATE ·group functions·DISTINCT operator
―  이들 SQL문는 best response를 목적으로 최적화될 수 없습니다.
―  위의 경우 첫 번째 row를 반환하기 전에 SQL문에 접근되는  모든 행들을 retrieve해야만함.
―  이런 SQL문에 대해 힌트를 쓰면 optimizer는 cost-based approach를  사용하고, best throughput을 목적으로 최적화.
―  SQL문에 ALL_ROWS나 FIRST_ROWS 힌트를 기술하고, data dictionary가 그 SQL문에의해 접근되는 table에 대해 어떤 statistics도 포함하지 않는다면, optimizer는 내부적으로 execution plan을 선택하고, missing statistics를 추정할 default statistics 값을 사용.
―  이 추정치(estimates)는 ANALYZE명령에 의해 생성되어진 것만큼 정확하지는 않음.
―  ANALYZE명령을 사용하여 Cost-based optimization을 사용하는 SQL문에 의해 접근되는모든 table에 대한 statistics를 생성해야 함.
―  Access path를 위한 힌트 또는 ALL_ROWS나 FIRST_ROWS 힌트를 가지는 join operation을 기술합니다면, optimizer는 힌트에 의해 기술된 join operation들과 access paths를 우선적으로 취함.

 

실행 순서 방법을 위한 SQL 힌트
―  각 힌트들은 table에 대한 access method를 제안
―  힌트중의 하나를 기술하는 것은 access path가 index 나 클러스터와 SQL문의 의미구조의존재를 기본적으로 이용할수 있다면 기술된 access path를 선택
―  힌트가 access path를 이용할수 없다면 optimizer는  그것을 무시.
―  SQL문에서 정확하게 access되는 table을 기술
―  SQL문이 table에 대한 alias를 사용하면, 힌트에서 table의 이름보다는 alias를 사용.
―  table의 이름이나 alias 는 local database에 있는 한 table에 대한 하나의 synonym이나하나의 table을 의미함.

 

∮ FULL
―  FULL 힌트는 table에 대해 full table scan을 선택
―  FULL 힌트의 문법은 FULL(table)
―  (table)에는 full table scan을 수행하는 table의 alias나 name을 기술합니다.
―  예 : ACCOUNT table에 WHERE절의 조건에 의해 사용가능한 ACCNO 칼럼에 대한 index가있음에도 불구하고, 오라클은 이 SQL 문을 실행할 ACCOUNTS table에 full table scan을 수행.
SELECT  
/*+ FULL(a) Don’t use the index on ACCNO */ accno, bal FROM accounts a   WHERE accno = 7086854; NOTE·  ACCONTStable이 alias A를 가지기 때문에 힌트는 table의 이름이 아닌 alias로 table을표현.·  FROM 절에 table의 이름이 기술되었음에도 불구하고, 힌트에서 는 schema names을 기술하지 않는다.

 

ROWID
―  ROWID힌트는 table에대해 ROWID에의한 table scan을선택
―  ROWID 힌트의문법은ROWID(table)
―  (table)에는 ROWID에의한 table scan이이행되어지는 table의 alias나이름을기술.

 

CLUSTER
―  CLUSTER힌트는 table에대해 cluster scan을선택
―  CLUSTER 힌트의문법은CLUSTER(table)
―  (table)에는 cluster scan에의해접근되는 table의이름이나 alias를기술.SELECT –+ CLUSTER emp, ename, deptnoFROM emp, deptWHERE deptno = 10 AND emp.deptno = dept.deptno;

 

HASH
―  HASH힌트는 table에대해 HASH scan을선택
―  HASH 힌트의문법은 HASH(table)
―  (table)에는 hash scan에의해접근되는 table의이름이나 alias를기술

 

INDEX
―  INDEX힌트는 table에대해 index scan을선택

―  INDEX 힌트의문법은

table : scan될 index와관련있는 table의이름이나 alias를기술

index : index scan이수행될 index를기술

―  힌트는하나이상의 indexes들을기술
· 힌트가하나의사용가능한 index를기술합니다면, optimizer는 index에서한개의 scan을수행.
· optimizer는 full table scan이나 table에있는다른 index에대한 scan은수행하지않음.
· 힌트가사용가능한 index의리스트를기술합니다면, optimizer는리스트에있는각각의 index에대한 scan을하는데드는비용을고려한후에가장적은비용이드는 index scan을이행
· 이 access path가최저의비용을가진다면 optimizer는이리스트로부터여러 index를 scan하고그결과들을 merge.
· optimizer는 full table scan이나힌트에있지않은 index scan은고려하지않음.
· 힌트가어떤 index도기술하지않았다면, optimizer는 table에있는사용가능한 index를각각 scan한비용을고려한후에 lowest cost를가진 index scan을수행.
· 이 access path가최저비용을가진다면 optimizer는 muliple index를 scan하고그결과값을 merge.

SELECT name, height, weightFROM patientsWHERE sex=’M’·  sex의열은 index되어있고, 이칼럼은 ‘M’과 ‘F’의값을가짐.·  병원에남자의수와여자의수가동일하다면, 이질의는연관된 table의행의최다퍼센트를반환하고, full table scan이 index scan보다는더빠르게됩니다.·  병원의환자중남자의비율이매우적다면, 질의는관련된 table의행에대해적은비율을반환하고, 이경우에는 index scan이 full table scan보다더빠릅니다.
―  각 disinct column value의발생수는 optimizer에게별로유용하지않다(도움이되지않는다.)― cost-based approach는각각의값들이각각의행에서나타나는빈도수가동일하다고가정을합니다.
―  한칼럼이단 2개의다른값들(distinct values)을가진다면 optimizer는그두값들이각각 row의 50%로정도나타난다고가정합니다그래서 cost-based approcah는 index scan보다는 full table scan을선택하곤합니다.
―  WHERE절에있는값이모든 row에대해매우적은퍼센트를가진다면, 힌트에 index scan을사용하여 optimizer가강제로 index scan을사용하게할수있습니다.
―  아래문장에서 INDEX 힌트는 SEX_INDEX에대해 index scan을선택합니다.·

SELECT /*+ INDEX(patients sex_index) Use SEX_INDEX, since there are few male patients */name, height, weightFROM patientsWHERE sex = ‘M’;

 

FULL 힌트와 INDEX 힌트의비교예제
―  1. EMPtable의총건수는 10,000건, DEPTtable의총건수는 2400건.
―  2. EMPtable에서 empno, ename, sal을
SELECT
―  3. WHERE절의조건은 JOB 필드의 ‘SALESMAN’값을검사
―  4. JOB_INDEX존재.
―  5. JOB필드에는 2개의값이존재(MANAGER-(9,751건/10,000건), SALESMAN-(249건/10,000건))·  EMP, DEPT table을ANALYZE함.·  sql_trace를 true로·  OPTIMIZER_GOAL 은ALL_ROWS
―  예제 1analyze table emp estimate statistics;analyze table dept estimate statistics;alter session set sql_trace = true;alter session set optimizer_goal = all_rows;SELECT empno, ename, salfrom empwhere job = ‘SALESMAN’;SELECT /*+ full(emp) */ empno, ename, salfrom empwhere job = ‘SALESMAN’;

SELECT /*+ index(emp job_index) */ empno, ename, salfrom empwhere job = ‘SALESMAN’;

·  OPTIMIZER_GOAL 은FIRST_ROWS
―  예제 2analyze table emp estimate statistics;analyze table dept estimate statistics;alter session set sql_trace = true;alter session set optimizer_goal = first_rows;SELECT empno, ename, salfrom empwhere job = ‘SALESMAN’;

SELECT /*+ full(emp) */ empno, ename, salfrom empwhere job = ‘SALESMAN’;

SELECT /*+ index(emp job_index) */ empno, ename, salfrom empwhere job = ‘SALESMAN’;

 

∮ INDEX_ASC
―  INDEX_ASC힌트는 table에대한 index scan을선택
―  이 SQL문이 index range scan을사용합니다면, Oracle은 index된값들을오름차순으로정렬한 index entry들을 scan.

―  INDEX_ASC 힌트의문법은

―  각파라메타는 INDEX 힌트에서와같은목적을의미.

―  range scan에대해서오라클의 default behavior는 index된값에대해오름차순으로정렬하고그 index entry들을 scan하는것이므로이힌트는일반적으로 index 힌트보다더나은점은없습니다.

 

∮ INDEX_DESC
―  INDEX_DESC힌트는 table에대해 index scan을선택

―  만약 SQL 문이 index range scan을사용합니다면, 오라클은 index된값들을내림차순으로정렬한 index entry들을 scan.

―  INDEX_desc 힌트의문법은

 

―  각파라메타는 INDEX 힌트에서와같은목적을의미.
―  이힌트는 table보다 INDEX를더많이접근하므로 SQL문에영향을주지않음.
―  아래의 SQL문은 index된값에대해서항상오름차순으로정렬된 index range scan을수행

CREATE TABLE tank_readings (time DATE CONSTAINT un_time UNIQUE,temperature NUMBER);

―  table의각행들은한시점에서시간과온도를저장.
―  TIME칼럼에대해 UNIQUE 제약을주면 table이동일한시점에서한번만내용을읽도록합니다.
―  오라클은 TIME 칼럼에강제로 index를수행.
―  특별한 T시간에대해서읽은가장최근의온도를 SELECT 하는 complex query를생각해보자.
―  Subquery는온도를읽는시점 T나 T이전의가장최근시간의값을반환.
―  Parent query는그시간에대한온도를찾는다.


SELECT
temperatureFROM tank_readingsWHERE time = (SELECT MAX(time)

              FROM tank_readingsWEHRE time <= TO_DATE(:t) );

 

―  위 SQL문에대한 execution plan은아래그림과같습니다.

 

―  위 SQL문장을실행시키면, 오라클은아래와같은 operations를실행.

 

· step 4와 3은 subquery를실행.

– step 4는시간 T와같거나더적은모든 TIME 값들을반환할 UN_TIME index의 range scan을수행.

– step 3는 step 4로부터최대 TIME값을선택하고그값을반환. ·step 2 와 1은 parent query를실행.

– step 2는 step 3에의해반환된 TIME 값에맞는 UN_TIME index의 unique scan을수행하고관련된 ROWID를반환.

– step 1은 step 2에의해반환된 ROWID를사용하여 TANK_READING table을접근하고 TEMPERATURE 값을반환.

 

― Step 4에서오라클은오름차순으로정렬된 index에있는 TIME 값을 scan.
―  오라클은첫번째 TIME값이 T보다더큰경우에 scaning을중지하고그후에 step 3에서 T값과같거나더적은모든값을반환.
―  INDEX_DESC 힌트를사용하면 index로부터단하나의 TIME값을읽어오는질의사용가능.


SELECT
/*+ INDEX_DESC(tank_readings un_time) */ temperature FROM tank_readings WHERE time <= TO_DATE(:t) AND ROWNUM = 1;ORDER BY time DESC;

―  이것의 execution plan을아래그림과같습니다.

 

· step 3은 T와동일하거나더적은 TIME값을찾기위해 UN_TIME index를 range scan하고그와관련된 ROWID를반환.
· step 2는 step 3에의해반환된 ROWID값들로서 TANK_READING table에접근.
· step 1은 step 2로부터단하나의행을요구함으로 ROWNUM=1이라는조건을수행.

―  INDEX_DESC 힌트때문에 step 3은 T값부터시작하는내림차순으로정렬된 index에서 TIME값을 scan.
―  scan된첫번째 TIME값은 T이거나 T값보다는적은최대 TIME값입니다.
―  step 1은단하나의행을요구한후부터는 , step 3은첫번째 TIME값이후의 index entry에대해더이상 scan하지않는다.
―  default 행동이오름차순 index scan이므로 INDEX_DESC 힌트없이이질의를수행하면오라클은 table에서 T와같거나그보다적은최대시간을처음 scaning하는것보다최초의시간을 scaning함으로서시작하게됨. step1은최초의시간에대한온도를반환하게됩니다.
―  위질의에서좀더빨리이복합질의에서요구하는온도를반환하려면 INDEX_DESC 힌트를사용해야만합니다.

 

AND_EQUAL
―  AND_EQUAL힌트는몇몇의 single-column index에대한 scan을 merge하는 access path를사용하는 execution plan을선택
―  이 AND_EQUAL 힌트의문법은

table : merge할 index와연관된 table의이름이나 alias를기술.

index : index scan을수행하는 index를기술― 최소 2개이상최대 5개이하의 index를기술해야합니다.

 

 

USE_CONCAT
―  USE_CONCAT 힌트는 OR 조건을 UNION ALL set operator를사용하는 compound query로변환
―  이변환은 UNION ALL set operations을사용하는질의가이를사용하지않을때보다비용이더적을경우에만발생

 

조인순서를위한 SQL 힌트
ORDERED 힌트는 join order를제안

 

ORDERED
―  ORDERED 힌트는 FROM절에 table이나타나는순서대로 table을 join시킨다.
―  예를들어, 아래 SQL문은 table TAB1과 table TAB2를조인한후에그결과와 table TAB3을조인합니다.
SELECT
/*+ ORDERED */ tab1.col1, tab2.col2, tab3.col3FROM tab1, tab2, tab3WHERE tab1.col1 = tab2.col1 AND tab2.col1 = tab3.col1;

―  SQL문에서 ORDERED 힌트를생략하고 join를수행하면, optimizer가 table을 join할순서를선택

―  각 table에서 SELECT 해오는행의수에대해알고있다면 join 순서를기술하는 ORDERED 힌트를사용하는것이좋다.

―  사용자가 inner 와 outer table을선택하는것이 optimizer가할수있는것보다나을수도있습니다.

 

Table 조인방법 SQL 힌트
● SQL문에서나타나는조인된 table을정확하게기술해야만합니다.

● SQL문이 table의 alias를사용합니다면힌트에서도 table의이름보다는 alias를사용해야만합니다.

● table의이름이나 alias는 local database에 table의 synonym이나 table을가지고있어야만합니다.

● USE_NL과 USE_MERGE 힌트는 ORDERED 힌트를사용해야만합니다.

● 오라클은참조된 table이조인에서강제로 innertable이될때이힌트를사용해야만합니다.

● 참조된 table이 outer table이라면이힌트들을무시합니다.

 

USE_NL
―  USE_NL 힌트는 table을적는부분에 table 기술된 table은 inner table로서사용하여 nested loops로서다른 table의 row source와기술된 table을 join하게합니다.
―  USE_NL 힌트의문법은

 

 

table : nested loops join의 inner table로서사용될 table의이름과 alias입니다.

―  예를들어서, ACCOUNTS와 CUSTOMERS table을조인하는 SQL문이있다고생각해보자. 이들 table들은 cluster에함께저장되지않았다고가정합니다.

SELECT accounts.balance, customers.last_name, customers.first_nameFROM accounts, customersWHERE accounts.custno = customers.custo;

―  cost-based approach의 default 목적은 best throughput이므로이 optimizer는좀더빨리질의에의해 SELECT 된모든행들을반환하기위해 nested loops operation이나 sort-merge operation중하나를선택합니다.
―  그러나질의에의해선택된첫번째행만반환할때필요시간이매우적어야할경우에는 best throughput보다 best response time으로 SQL문을최적화하는것이더낫다.
―  그렇게하려면 USE_NL 힌트를사용함으로서 optimizer가 nested loops join을강제로선택하게할수있습니다.
―  SQL문에서 USE_NL 힌트는 CUSTOMERStable을 inner table로가지는 nested loop를선택


SELECT
/*+ ORDERED USE_NL(customers) Use N-L to get first row faster */accounts.balance, customers.last_name, customers.first_name FROM accounts, customers  WHERE accounts.custno = customers.custno;

―  많은경우에 nested loops join은 sort-merge join보다는더빨리첫번째행을반환합니다.
―  Nested loop join은한 table로부터첫번빼 SELECT 한행을읽은후에첫번째행을반환할수있고, 다른 table에서첫번째로일치하는행을찾고그것들을결합합니다.
―  반면에 sort-merge join은양 table에서 SELECT 한모든 row들을읽고정렬한후각각의저장된 row source의첫번째행들을결합할때까지첫번째행을반환할수없습니다.

 

USE_MERGE
―  USE_MERGE 힌트는오라클이 sort-merge join으로각 table을조인하게끔하는방법입니다.
―  USE_MERGE 힌트의문법은

 

병렬쿼리실행을위한 SQL 힌트

 

CACHE
―  CACHE 힌트는 full table scan이수행됐을때힌트에있는 table에대해 retrieve된블록들은버퍼캐시에있는 LRU list의가장최근(most recently)에사용되어진것의끝에위치
―  이 option은 small lookup table에유용하다. CACHE 힌트는 table의 default caching specification을무시
SELECT /*+ FULL (scoot_emp) CACHE(scott_emp) */ enameFROM scott.emp scott_emp;

 

NOCACHE
―  NOCACHE 힌트는 full table scan이수행됐을때힌트에있는 table에대해 retrieve된블록들은버퍼캐시에있는 LRU list의가장오래전(least recently)에사용되어진것의끝에위치
―  버퍼캐수에 blocks의일반적인행동
SELECT /*+ FULL (scoot_emp) NOCACHE(scott_emp) */ enameFROM scott.emp scott_emp;
구문연계를고려하는 SQL 힌트
●  SQL이융통성이있는언어이기때문에하나이상의 SQL문이 Application을필요로할것입니다.
●  2개의 SQL문이동일한결과를산출함에도불구하고, 오라클은 2중의하나가더처리속도가빠릅니다.
●  execution plans을비교하기위해 EXPLAIN PLAN SQL문의결과와두 SQL문의비용들을사용할수있습니다.

 

두 SQL문에대한 execution plan 비교
● 첫번째 SQL문과그것에대한 execution plan

SELECT dname, deptnoFROM deptWHERE deptno NOT IN(

SELECT deptno FROM emp);

 

― Execution Plan with Two Full Table Scans

 

 

― step3을통해오라클은 DEPTNO 칼럼에 index가있음에도불구하고 EMPtable을 full table scan함으로서위 SQL문을실행합니다는것을알수있습니다.

 

― full table scan은time-consuming operation을할수있습니다.

 

― EMPtable을찾는subquery에 index사용이가능한 WHERE절이없기때문에오라클은 index를사용할수없습니다.

―  그러나, 아래의 SQL문은 index에접근함으로서동일한행을 SELECT 합니다.

 

SELECT dname, deptnoFROM deptWHERE NOT EXISTS(

 

SELECT deptnoFROM empWHERE dept.deptno = emp.deptno);

 

― Execution Plan with a Full Table Scan and an Index Scan

― subquery의 WHERE절이 EMPtable의 DEPTNO칼럼을사용하므로 DEPTNO_INDEX를사용할수있습니다.

― index의사용은 execution plan의 step3에서하게됩니다

―  DEPTNO_INDEX의 index range scan은첫번째문장에서 EMP table의 full scan하는것보다시간이더적게걸린다.
―  첫번째 query는 DEPT table에서모든 DEPTNO를가져오기위해 EMP table을한번 full scan합니다.

― 이런이유로두번째 SQL 문은첫번째보다는더빠릅니다.

― Application에 NOT IN operator를사용하는 SQL문를가진다면 NOT EXISTS operator를사용해서그것들을다시써라. 이것은 index가있다면그 index를사용할수있게해줄것입니다.

 

기존 SQL문을튜닝하는방법
  존재하는 application에서 SQL 문을튜닝하는것은새로운문장을기록하는것과는다른작업(task)입니다.

  비록요구된지식이같을지라도프로세스는다르다.

  튜닝하기위한 application에서특별한문장을다음과같이함으로써분리해야합니다.

· application에익숙하라.
· SQL trace를이용하여특별한문제문장을분리하라.

 이전절에서논의했던새로운 SQL 문장을기록하고, index, 클러스터, 해싱, 힌트를 하기 위한지침을 이용하여문장을 튜닝 할 수 있습니다.

 

Know the Application
―  application과 SQL 문장과 data에익숙해져야합니다.
―  만약당신이 application을설계하고개발하지않았다면그것을한사람에게의견을물어보라.
―  application이하는것을기록하라.

· application을이용하는 SQL 문은무엇인가?

· application이처리하는데이타는무엇인가?

· 데이타의특징과 distribution은무엇인가?

· applicatin의무슨 operation이 data를실행하는가?

―  application 사용자들과성능에대해이야기해보라.
―  application의어떤부분을식별하기위해서그들이성능향상의필요를느끼는지를물어보라.
―  가능하면개인적인 SQL 문장을위해서이부분들이적어질때까지좁혀라.

 

Use the SQl Trace Facility
―  오라클은성능을측정하기위하여진단에도움이되는 tool을몇가지제공합니다
―  appllicatin을튜닝하는데특별히도움이되는 tool중에하나는 SQL trace 입니다.
―  SQL trace facililty는오라클에의해처리된각 SQL 문장을위한통계를생성합니다.
―  통계는다음을나타낸다.

· SQL 문장이파싱, 실행, 페치된횟수
· 각 SQL 문장을처리하는데필요한시간
· 각 SQL 문장과관련된메모리와디스크 access
· 각 SQL 문장을처리하는 row의수
―  SQL trace facility는또한 EXPLAIN PLAN 명령을이용하여 execution plan을생성할수있습니다.

 

Tuning Individual SQL statements
―  사용중인사용자응용을수정하지않고 SQL문의변경된문법을탐색할수있음을명심하라.
―  사용자가존재하는 SQL문의비용과실행계획을비교하고고려하는문장을변경하는것은단순히 EXPLIAN PLAN을이용합니다.
―  만약사용자가 SQL문의 tune을위해새로운 index를생성하면사용자는 optimizer가응용이실행될때마다 index를사용할것인지를결정하기위해 EXPLAIN PLAN 명령을사용할수있습니다.
―  만약사용자가현재 parse된문장을 tune하기위해새로운 index를생성하면 Oracle은 SQL 문에서이 index를사용하지않는다.
―  SQL 문장이다시실행되면 optimizer는자동적으로새로생성된 index를사용하기위해새로운실행계획을선택합니다.
―  만약사용자가분산 SQL 문을 tune 하기위해원격데이타베이스의 index를생성하면 optimizer는 SQL문이다시실행될때이 index를고려합니다.
―  또한사용자는 SQL 문장에대한실행계획이 optimizer 보다더효과적으로사용할수있도록 tune합니다는것을명심하라.
―  예를들어사용자가하나의 SQL문을사용하기위해 index를생성하면 optimizer는사용자의응용에서다른문장을실행하기위해그 index를선택합니다.

By haisins

오라클 DBA 박용석 입니다. haisins@gmail.com 으로 문의 주세요.

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다