전체 글 298

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) < ..

부분범위 처리와 전체 범위처리

user 테이블이 있는데 1000만건입니다. select * from [user] 를 실행하면 언제 부터 결과를 받을 수 있나요? 읽는 데이터 모두가 답입니다. 데이터베이스는 운반 단위에 차면 바로 바로 응답합니다. 그래서 0.0001초 만에 결과를 받기 시작합니다. 이 것이 바로 부분 범위 처리 입니다. select * from [user] order by name를 실행하면 언제 부터 결과를 받을 수 있나요? 이것은 전체를 읽어서 name로 소트를 해야만 결과를 받을 수 있습니다. 이 것이 바로 전체 범위 처리입니다. 전체 범위 처리 : 풀 스캔 후 가공하여 Array Size(운반 단위) 만큼 추출되어야 결과를 얻음 부분 범위 처리 : 조건을 만족하는 Row 수가 Array Size에 도달되면 결과..

아크 모델(exclusive or)에서의 주의점

다음과 같은 모델을 아크라고 하며 exclusive or 관계 입니다. select A.missionno, case A.owner_flag when 1 then B.name when 2 then C.guildname end name from missions A, [user] B, guild C where A.quest_id = 1 and ((A.owner_flag = 1 and A.userno = B.userno) or (A.owner_flag = 2 and A.guildno = C.guildno)) 이 SQL을 실행하니 희안하게도 같은 이름이 복사가 되어 보여 집니다. 옆사람에게 물으니, "에이~ 이런 것도 모르세요? distinct 있자나요~" 그래서 신기하게도 distinct 하나만 붙여주니 원하는..

리커시브 모델의 활용

부서 코드 테이블을 다음과 같이 계층형으로 표현합니다. 부서 ID가 다음과 같이 입력되어 있습니다. 1120이 테라PC실이인데 상위 조직이 1100이 아니라 1200으로 바뀌게 되면 1120이 1220으로 변경되어야 합니다. 그런데 이것만 바꾸는 것이 아니라 아래 모든 자식들도 바꾸어 주어야 합니다. 부서 코드 테이블 뿐만 아니라 관계된 테이블이 있다면 모두 다 업데이트 해야 합니다. 사원에 부서 코드가 있었다면 관계 있는 모든 사원의 부서 코드가 업데이트 되어야 합니다. 이는 부서 코드 테이블에 상위 부서 컬럼이 추가 되면 해결됩니다. 상위 부서로서 '리커시브 모델'로 표현한 것입니다. 리커시브로 설계 했을 뿐인데 상위 조직이 바뀌면 상위 부서 ID 하나만 수정하면 됩니다. Happy!!!

테이블 조인 하면 느리다?

다음의 1번과 2번 중 어느쪽이 더 빠를까요? 1. Join이 빠르다. select A.userno, A.name, B.guildname from [user] A JOIN guild B ON A.guildno = B.guildno 2. Join하지 않는 것이 빠르다. select userno, name, guildname from [user] 1번이 더 빠릅니다. 디스크 IO 보다 CPU와 메모리가 훨씬 빠르기 때문입니다. 퍼포먼스에 가장 큰 영향을 주는 것이 디스크 IO 입니다. 그럼 디스크 IO량이 어떻게 되는지 따져봅시다. 1번은 108 * 100 바이트(약 1만)+ 32 * 10만 바이트(약 320만) = 약 321만 바이트 2번은 132 * 10만 바이트(약 1320만) 바이트 = 약 1320만..

옵티마이저 맛보기

우리는 데이터베이스에게 SQL Query를 통해 문제를 내고 데이터베이스는 옵티마이저는 최선을 다해 그 결과를 가져옵니다. 이 옵티마이저는 우리가 생각하는 이상으로 아주 뛰어난 녀석입니다. Nested loop join을 한다면 여러분이 옵티마이저라면 guild와 user 두 테이블중 어떤 테이블을 먼저 드리아빙 하겠습니까? user 테이블을 읽고 guild테이블을 읽음 반대로 guild 테이블 읽고 user 테이블을 읽음 select B.guildname, A.userno, A.name from [user] A, guild B where A.guildno = B.guildno Nested loop join : 어느 한 쪽 테이블을 먼저 드라이빙해서 조인하는 방식입니다. select B.guildname..

[RDBMS] 대용량 데이터베이스 솔루션 - MS-SQL로 내용 정리

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

[MSSQL] 데이터 저장 구조

데이터 저장의 저장의 기본 단위가 '페이지'입니다. 페이지 관리의 기본 단위가 '익스텐트'입니다. [페이지] SQL Server의 페이지 크기는 8KB입니다. 1MB당 128페이지가 존재합니다. 각 페이지는 96바이트의 머리글로 시작하여 머리글에는 시스템 정보가 저장됩니다. 머리글 다음에 데이터 행과 이에 대응하는 행 오프셋 정보를 담고 있다. 구조는 다음과 같습니다. 대용량 행(varchar, nvarchar, varbinary, sql_variant등)의 경우에는 8KB를 초과하는 경우가 습니다. 실제 행들이 여러 페이지에 걸쳐 있을 수 없지만 이러한 행들은 전체 행의 8060바이트를 초과하면 ROW_OVERFLOW_DATA 할당 단위에 있는 페이지로 동적으로 옮기고 원래 페이지에는 이에 대한 24바..

Nested Loops/Sort Merge/Hash 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 : 테이블 각자 소트하여 머지 합니다. : 양쪽 테이블..