RDBMS 16

대용량 데이터베이스 솔루션 with MSSQL

대용량 데이터베이스 솔루션 1, 2권은 제가 20년 전에 데이터베이스 공부를 위해 읽었던 책입니다. 이 책들은 제가 데이터베이스를 대하는 임하는 자세를 바꾸게 해 준 책입니다. DBA에게는 바이블과 같은 책이기도 합니다. 이 책들의 내용들 중에 서버 개발 프로그래머들이 꼭 필요한 내용들을 정리하였습니다. 이 책은 오라클로 설명하고 있으며 오라클은 게임 개발에서 거의 사용되지 않고 있고 주로 많이 사용하는 MS-SQL에 맞추어 내용을 정리 하였습니다. 여러분에게 관계형 데이터베이스 즉 RDB 개발은 어려웠나요? 제 생각에는 대부분의 서버 개발 프로그래머는 DB 개발을 쉬워 해요. SQL 문법을 익히기만 하면 원하는 결과를 쉽게 얻을 수 있기 때문이죠. SQL 문법 자체는 쉽기 때문에 이렇게 생각합니다. 이..

독서 리뷰 2020.09.09

인라인 뷰의 활용

단계적 조인을 위한 활용 전체적인 일량을 줄이기 위해 사용하는 방법 - group by 후 조인 내가 추출할 그룹의 레벨인 테이블로 group by 한 후 조인하면 많은 불필요한 조인을 줄일 수 있습니다. select y.상인이름 sum(x.판매수량), sum(x.판매금액) from 상품목록 x, 상인 y where x.상인코드 = y.상인코드 and x.아이템코드 = @아이템코드 group by y.상인이름 상품 목록을 '상인' 레벨로 추출 후 조인하였습니다. select y.상인이름, 수량, 금액 from (select 상인코드, sum(판매수량) 수량, sum(판매금액) 금액, from 상품목록 where 아이템코드 = @아이템코드 group by 상인코드) x, 상인 y where x.상인코드 =..

서브 쿼리 활용

'제공자 역할' 서브 쿼리라면 먼저 수행됩니다. 서브 쿼리의 결과를 메인 쿼리로 제공해주며 메인 쿼리의 인덱스로 잡혀야 겠습니다. 서브 쿼리 안에 메인 쿼리의 컬럼이 없어야 합니다. '확인자 역할' 메인 쿼리가 먼저 실행되고 서브 쿼리가 실행됩니다. 서브 쿼리 내에 메인 쿼리의 컬럼이 있다면 '확인자 역할'을 합니다. - 잘못 사용된 예 REQT 테이블 2000만 건(월 500만건 생성) INDEX는 cust_no + req_ym update reqt x set in_amt = in_amt + @amt where req_ym = '202005' and custno in (select custno from cust y where pay_cust = @cust and x.custno = y.custno) 지..

SQL IN의 특징과 IN의 활용

- OR 연산의 해소 select ... from tab1 x, tab2 y, tab3 z where ... join_conditions... and ((@선택 = 1 and 구분 = 10 코드 = @코드) or (@선택 = 2 and 구분 between 20 and 30 and 코드 = @코드)) in과 case when 으로 가능한한 OR를 해소 시키세요. select ... from tab1 x, tab2 y, tab3 z where ... join_conditions... and 구분 in (case when 선택 = 1 then 10 else 20 end, case when 선택 = 2 then 30) and 코드 = @코드 - IN 연산자의 특성 IN은 n개의 = 입니다. COL1 BETWEE..

SQL 집합의 가공

합집합 : UNION 차집합 : EXCEPT 교집합 : INTERSECT 집합간의 곱(cartesian product) : Join 정의역 : WHERE 조건으로 변경 and : 정의역 범위 줄어듬 or : 정의역 범위 늘어남 치역 : SELECT 항목, group by로 변경 Join 관련된 다른 집합을 찾아 오는 것이 아닙니다. Join은 집합간의 곱으로 생각하세요. "1쪽과 M쪽을 조인한다"는 "1 * M만큼의 데이터가 M쪽을 기준으로해서 1쪽에 복제되서 만들어진다."로 생각해야 합니다. 세로 데이터를 가로로 바꿀때 : sum(case when ...) 가로를 세로로 바꿀때 : 1 x n 을 Join 하여 n건으로 복제해서 얻음 데이터를 복제 : copy_t를 이용하여 묻지마 조인하여 복제 - 카피..

DB 절차적 사고 VS 집합적 사고

절차적으로 개발하면 하나 하나에 대한 처리를 던지므로 옵티마이저는 최적화 할 것이 거의 없습니다. (노가다만 하는 거죠) 조회 후 업데이트 또는 입력 select.Execute() while (select.Fetch()) { if(조건?) { update테이블.Execute(); } else { insert테이블.Execute(); } } merge 테이블 using (select ...) on ( 조건 ) when matched then update ... when not matched then insert ... 아이템 강화의 예 for(재료 아이템 종류) { if(아이템이 0개인가?) { delete아이템.Execute(); } else { update아이템수.Execute(); } } update..

DB 테이블 클러스터링 팩터

원하는 정보를 얻기 위해 얼마나 모여 있느냐가 '클러스터링 팩터'입니다. 잘 모여 있을 수록 디스크 IO 효율이 높아져서 성능 또한 좋습니다. 예를 들어, 6건을 얻어 오는데 피지컬 블럭을 2개를 엑세스해서 얻어왔고 3건을 얻기 위해 피지컬 블럭 3개를 엑세스해서 얻어 온다면 6건을 읽는 것이 더 빠릅니다. Index 구조 랜덤 엑세스, 싱글 블럭 IO Clustering Table(Clustered index) 랜던 엑세스를 줄일 수 있으며 멀티 블럭 IO를 할 수 있어서 검색이 빠릅니다. 지정된 컬럼값의 순서대로 로우를 저장시키는 방법 엑세스기법이 아니라 엑세스 효율향상을 위한 물리적 저장기법 검색의 효율을 높여주나 입력, 수정, 삭제시는 부하 증가 분포도가 넓을 수록 오히려 유리 Sorting Ta..

Nested Loop/Sort Merge/Hash Join

다음의 SQL로 두 테이블을 Join합니다. SELECT a.FLD1, ..., b.FLD1,... FROM TAB1 a, TAB2 b WHERE a.KEY1 = b.KEY2 AND a.FLD1 = 'AB' AND b.FLD2 = '10' 1. Nested Loop Join : 어느 한쪽을 드라입밍 해서 조인하는 방식 : 실행 계획의 아이콘입니다. 중첩 루프 즉, for 루프 두 개를 연상하게 합니다. 순차적 ( 부분범위처리 가능 ) 종속적 ( 먼저 처리되는 테이블의 처리범위에 따라 처리량 결정 ) 먼저 처리되는 테이블의 범위가 넓다면 더 많은 처리량이 생기는 거죠. 랜덤 액세스 위주 연결고리 상태에 따라 영향이 큼(key2 = key1) 주로 좁은 범위 처리 에 유리 2. Sort Merge Join ..

DB 옵티마이저

옵티마이져의 목표? SQL로 요구된 결과를 최소의 비용으로 처리할 수 있는 처리 경로를 결정한다. SQL과 옵티마이저 SQL은 처리 절차를 기술하는 것이 아니라, 결과에 대한 요구일 뿐입니다. 처리 절차는 옵티마이저가 생성합니다. 즉 진정한 프로그래머는 옵티마이저입니다. 없는 처리 방법을 생성해주는 것이아니라, 이미 존재하는 처리 방법을 단지 찾아줄 뿐입니다. 사용자가 부여한 영향 요소에 따라 논리적으로 존재하는 처리 방법이 달라집니다. (결국, 책임은 사용자에게 있습니다.) 동일한 결과를 얻을 수 있는 경로는 많으나 효율성의 차이는 큽니다. 옵티마이저는 절대 전지전능하지 않습니다. : 그래서 우리의 역할이 필요 합니다. 옵티마이져에 영향을 미치는 요소 SQL의 형태에 따라 인덱스 클러스터링 연산자의 형..

인덱스의 제대 사용하자

인덱스를 사용하지 않는 경우 index 컬럼의 변경 select userno, name from [user] where SUBSTRING(name, 1, 7) = 'user123' Not operator select userno, name from [user] where name 'abc' null, not null select userno, name from [user] where name is not null 옵티마이저의 취사선택 SQL 작성 규칙 좌변을 가공하지 마라 where SUBSTRING(name, 1, 3) = 'abc' → where name like 'abc%' where sal * 12 = 2000 → where sal = 2000 / 12 where isnull(cost, 0) < ..