분류 전체보기 294

리커시브 모델의 활용

부서 코드 테이블을 다음과 같이 계층형으로 표현합니다. 부서 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 : 테이블 각자 소트하여 머지 합니다. : 양쪽 테이블..

[MSSQL] 캐시 확인및 삭제

SQL 테스트시 다음의 명령을 실행 후 테스트합니다. -- 현재 데이터베이스의 모든 더티 페이지를 디스크에 쓰고 버퍼를 정리 CHECKPOINT GO -- 버퍼 풀 초기화 DBCC DROPCLEANBUFFERS GO -- 프로시저 캐시 초기화 DBCC FREEPROCCACHE GO 캐시 부분 확인및 삭제 방법 사용중인 캐시 추출 SELECT * FROM SYS.SYSCACHEOBJECTS WHERE [SQL] LIKE '%테이블이름%' SELECT plan_handle, st.text FROM sys.dm_exec_cached_plans CROSS APPLY sys.dm_exec_sql_text(plan_handle) AS st WHERE text LIKE N'%테이블이름%'; 원하는 캐시 삭제 DBCC..

[MSSQL] 힌트 사용 방법

WITH (INDEX( )) : 원하는 인덱스 사용 하도록 SELECT * FROM table WITH(INDEX()) WITH (INDEX(0)) : 풀 스캔 하도록 SELECT * FROM table WITH(INDEX(0)) WITH (NOLOCK) : 읽기 락 없이 테이블 읽게 SELECT * FROM table WITH(NOLOCK) INNER HASH JOIN / INNER LOOP JOIN : 쿼리로 Join 방식 결정 nested loop/hash merge join 결정 SELECT * FROM table A INNER HASH JOIN table2 B ON A.xx= B.xx SELECT * FROM table A INNER LOOP JOIN table2 B ON A.xx= B.xx {..

[MSSQL] 실행 계획의 subtree cost는 무엇인가?

쿼리의 실행 계획을 살펴 보면 아래와 같이 subtree cost항목이 항상 있습니다. 이것이 의미 하는 것은 현재 노드 하위의 모든 tree들의 총 cost가 얼마나 되는지를 표시 합니다. 특정한 사람의 데스크 탑 PC에서 수행해서 쿼리가 몇 초가 걸리는지를 측정한 값입니다. 이 값의 유래는 다음과 같습니다. the story goes that when the new query optimizer was developed for SQL server 7.0 in the Query Optimizer team there was a programmer called nick (I am sorry but I do not know his last name) ,he was responsible for calculati..

[MSSQL] copy_t 더미 테이블 만들기

copy_t는 테이블을 복제하여 원하는 데이터로 가공 할때 가장 많이 사용하는 더미 테이블입니다. create table copy_t ( seq int, seq_var varchar(2) ) with temp as ( select 1 as seq union all select seq + 1 from temp where seq < 99 ) insert into copy_t ( seq, seq_var ) select seq, replicate('0',2-len(cast(seq as varchar))) + cast(seq as varchar) from temp option(maxrecursion 0) 다음과 같이 더미 데이터가진 테이블을 생성합니다.