by-nc-sa     개발자, DBA가 함께 만들어가는 구루비 지식창고!

성능향상을 위해서는 튜닝하지 말고 디자인하라

Version 11 by study.gurubee
on 7월 18, 2011 17:32.


 
compared with
Current by study.gurubee
on 7월 21, 2019 21:10.


 
Key
These lines were removed. This word was removed.
These lines were added. This word was added.

View page history


There are 14 changes. View first change.

 * "튜닝"은 SQL 쿼리 또는 데이터 모델을 가리킬 수 있다.
 이 장에서 언급하고 싶은 것은 데이터 모델을 서투르게 디자인하면 그 어떤 SQL 튜닝도 도움이 되지 않는 것이다.
  * 이 장에서 언급하고 싶은 것은 데이터 모델을 서투르게 디자인하면 그 어떤 SQL 튜닝도 도움이 되지 않는 것이다.
  
\\
  
 h2. 6.1 일반적인 데이터 모델을 사용하지 말라
 * 애플리케이션이 "최상의 융통성"을 위해 일반적인 데이터 모델 위에 구축되거나 성능에 저해되는 방식으로 구축되는 것은 드문 일이 아니다.
예를 들어, 네 개의 테이블을 이용하여 거의 모든 객체를 데이터베이스에 표현할 수 있다
  * 예를 들어, 네 개의 테이블을 이용하여 거의 모든 객체를 데이터베이스에 표현할 수 있다
  
 {code:SQL}
 create table objects (
  oid int primary key
 ,name varchar2(255)
 );
 create table attributes (
  attrId int primary key
 ,attrName varchar2(255)
 ,datatype varchar2(25)
 );
 create table object_Attributes (
  oid int
 ,attrId int
 ,value varchar2(4000)
 ,primary key (oid, attrId)
 );
 create table Links (
  oid1 int
 ,oid2 int
 ,primary key (oid1, oid2)
 );
  
 insert into attributes values ( 1, 'DATE_OF_BIRTH', 'DATE' );
 insert into attributes values ( 2, 'FIRST_NAME', 'STRING' );
 insert into attributes values ( 3, 'LAST_NAME', 'STRING' );
 commit;
  
 insert into objects values ( 1, 'PERSON' );
 insert into object_Attributes values( 1, 1, '15-mar-1965' );
 insert into object_Attributes values( 1, 2, 'Thomas' );
 insert into object_Attributes values( 1, 3, 'Kyte' );
 commit;
 insert into objects values ( 2, 'PERSON' );
 insert into object_Attributes values( 2, 1, '21-oct-1968' );
 insert into object_Attributes values( 2, 2, 'John' );
 insert into object_Attributes values( 2, 3, 'Smith' );
 commit;
  
 -- 모든 PERSON 레코드의 FIRST_NAME과 LAST_NAME을 가져오는 질의
 select max( decode( attrName, 'FIRST_NAME', value, null ) ) first_name
  ,max( decode( attrName, 'LAST_NAME', value, null ) ) last_name
  from objects
  ,object_attributes
  ,attributes
  where attributes.attrName in ( 'FIRST_NAME', 'LAST_NAME' )
  and object_attributes.attrId = attributes.attrId
  and object_attributes.oid = objects.oid
  and objects.name = 'PERSON'
  group by objects.oid;
 {code}
 
 \\
  
 !Ex9_1.jpg!
 
 \\
  
 !Ex9_2.jpg!
 
 \\
  
 !Ex9_3.jpg!
더 이상 테이블을 생성할 필요가 없다. 필요한 경우(ATTRIBUTES 테이블에 삽입함으로써) 즉시 열을 추가할 수 있기 때문이다.
 개발자는 제 마음대로 할 수 있으며 DBA는 이들을 제지할 수도 없다. 유연성이 극대화된 셈이다.
 그렇다면 이 모델의 성능은 어떠하겠는가? 비참, 처참, 끔찍 그 자체이다.
 이 모델에서는 쿼리 작성이 쉬워 보일 수 있다.
 예를 들면, 3월에 태어났거나 성이 스미스인 모든 사람들을 조회하고 싶다면
 모든 PERSON 레코드의 FIRST_NAME과 LAST_NAME을 구하는 쿼리를 작성하고 그 주위를 인라인 뷰로 감싸면 된다.
   
 \\
  
 * 더 이상 테이블을 생성할 필요가 없다. 필요한 경우(ATTRIBUTES 테이블에 삽입함으로써) 즉시 열을 추가할 수 있기 때문이다.
 * 개발자는 제 마음대로 할 수 있으며 DBA는 이들을 제지할 수도 없다. 유연성이 극대화된 셈이다.
 * 그렇다면 이 모델의 성능은 어떠하겠는가? 비참, 처참, 끔찍 그 자체이다.
 * 이 모델에서는 쿼리 작성이 쉬워 보일 수 있다.
 * 예를 들면, 3월에 태어났거나 성이 스미스인 모든 사람들을 조회하고 싶다면 모든 PERSON 레코드의 FIRST_NAME과 LAST_NAME을 구하는 쿼리를 작성하고 그 주위를 인라인 뷰로 감싸면 된다.
  
 {code:SQL}
 select *
  from ( select max( decode( attrName, 'FIRST_NAME', value, null ) ) first_name
  ,max( decode( attrName, 'LAST_NAME', value, null ) ) last_name
  ,max( decode( attrName, 'DATE_OF_BIRTH', value, null ) ) date_of_birth
  from objects
  ,object_attributes
  ,attributes
  where attributes.attrName in ( 'FIRST_NAME', 'LAST_NAME', 'DATE_OF_BIRTH' )
  and object_attributes.attrId = attributes.attrId
  and object_attributes.oid = objects.oid
  and objects.name = 'PERSON'
  group by objects.oid
  )
  where last_name = 'Smith'
  or date_of_birth like '%-mar-%';
 {code}
 
 \\
  
 !Ex9_4.jpg!
쿼리가 쉬워 보인다면 성능에 관하여 생각해 보라! 몇 천 개의 OBJECT 레코드와 수만 개의 OBJECT_ATTRIBUTES가 존재한다고 가정해 보면
 오라클은 첫 번째 쿼리를 통해 전체 내부 그룹을 처리하고 WHERE 절을 적용할 것이다.
  
\\
  
 * 쿼리가 쉬워 보인다면 성능에 관하여 생각해 보라! 몇 천 개의 OBJECT 레코드와 수만 개의 OBJECT_ATTRIBUTES가 존재한다고 가정해 보면 오라클은 첫 번째 쿼리를 통해 전체 내부 그룹을 처리하고 WHERE 절을 적용할 것이다.
  
 \\
  
 h2. 6.2 효율성을 염두에 두고 데이터 모델을 디자인하라
 * 데이터 모델은 가장 빈번하게 발생하는 쿼리에 대해 가장 효율적으로 응답할 수 있도록 디자인되어야 한다.
 
 * 처음부터 원활한 수행을 목표로 시스템은 디자인하므로 디자인 및 구현 과정에서 정확하게 예측할 수 없을 경우에만 튜닝을 실시한다.
  
h3. 6.2.1 쓰기 또는 읽기 위주로 디자인할까?
  \\
  
 h4. 6.2.1 쓰기 또는 읽기 위주로 디자인할까?
 * 팜 모델을 이용한 웹 기반의 내부용 달력 시스템 구축 사례
  
h3. 6.2.2 어느 모델이 효과적이었을까?
 * 사용자의 요구를 데이터 모델에 맞추는 것이 아니라 데이터 모델을 사용자의 요구에 맞추자
  \\
  
 h2. 문서에 대하여
 * 최초작성자 : [박상현],[이재광]
 * 최초작성일 : 2009년 9월 14일
 * 이 문서는 [오라클클럽|http://www.gurubee.net] [2009년 하반기 대용량데이터베이스 스터디] 모임에서 작성하였습니다.
 * {color:blue}*이 문서의 내용은 THOMAS KYTE 저, 박민호 역의 이펙티브오라클을 참고했습니다.*{color}
  
  h4. 6.2.2 어느 모델이 효과적이었을까?
 * 사용자의 요구를 데이터 모델에 맞추는 것이 아니라 데이터 모델을 사용자의 요구에 맞추자