728x90

김정선의 좋은 글을 찾아서……
SQL Server 인덱스 구성 전략(시리즈-3. 정렬된 파티션 인덱스)

 

 

사용자 삽입 이미지
김정선(jskim@feelanet.com)

필라넷 DB사업부 수석컨설턴트

SQLServer 아카데미/트라이콤 교육센터 강사

 

Microsoft SQL Server MVP

MCT/MCITP/MCDBA



Part 3: 오프라인, 직렬/병렬 파티셔닝(정렬된 파티션 인덱스 구성)

파티션 인덱스 구성에는 2가지 주요 범주가 있다:

-       정렬된(Aligned): 해당 개체(테이블)과 인덱스가 동일 파티션 스킴(scheme)을 사용하는 경우
(
역주: 본문에 schema로 적고 있다, 오타일까? 의도적인 것일까? ^^)

-       정렬되지 않은(Non-Aligned): 힙과 인덱스가 서로 다른 파티션 스킴을 사용한 경우

 

정렬된 파티션에 직렬 인덱스 구성

 

NL

                /       \

             CTS   Builder (write data to the in-build index)

                           \

                        [Sort] (order by index key) <-- optional

                             \

                          Scan (read data from source)

 

CTS: Constant Table Scan(이는 인덱스 구성자(builder)에게 파티션 ID를 제공하는 역할)

NL: Nested Loop

 

정렬된 파티션 인덱스를 구성하는 경우엔Constant Table Scan이 각각의 파티션 ID를 제공하고 이를 이용해 한 번에 하나의 파티션을 대상으로 인덱스 구성을 작업을 수행하며 Nested Loop 통해 이러한 작업을 반복 수행하게 된다. 각 정렬 테이블은 한 번에 하나씩 생성되어 처리되고 최종 b-tree 구성도 각 파티션 별로 하나씩 구성하므로 모든 파티션에 대해 정렬 테이블을 유지할 필요가 없다. 결국 한 번에 하나의 정렬 테이블만 있으면 된다.

 

이것이 필요한 디스크 공간에 미치는 영향은:

-       사용자 데이터베이스에서 정렬하는 경우(기본값) 각 파티션 별 해당 파일 그룹에서 정렬한다. 각 파일 그룹별로 2.2 x (파티션 크기) 만큼이 필요한 것이다. 예를 들어, 파일 그룹 FG1, FG2, FG3 3개의 파티션을 가지며 각 인덱스는 1GB, 2GB, 3GB를 소비한다면. 이 경우 FG1 2.2 x 1 = 2.2GB, FG2 2.2 x 2 = 4.4GB 그리고 FG3 2.2 x 3 = 6.6GB의 공간을 요구하는 것이다.

-       SORT_IN_TEMPDB = ON 인덱스옵션을 사용해서, tempdb를 정렬 공간으로 사용하는 경우 정렬 테이블에 대해 tempdb의 동일 공간을 재사용할 수 있게 된다. 한 번에 하나씩 파티션을 정렬하므로 실제론 2.2 x (가장 큰 파티션의 크기)만큼만 필요하게 되는 것이다.

(역주: 원문에는 위 사이즈에 대한 전체 크기 결과를 언급하고 있지만, 역자의 판단으로 설명과 결과가 맞지 않아 해당 부분의 설명은 생략했습니다)

 

메모리 고려 사항

한 번에 하나의 정렬 테이블만을 가진다면, 필요 메모리 크기는 최소 40페이지이다. 따라서 전체 메모리 계산식은

전체 메모리 = 최소 필요 메모리 + 추가 메모리*

 

*추가 메모리는 행 크기 x 예상 행 수로 계산되며 쿼리 최적화 프로그램에 의해서 제공된다.

 

 

 

정렬된 파티션에 병렬 인덱스 구성

파티션 인덱스에 대한 병렬 구성은 스캔과 정렬이 병렬로 수행되며 동시 실제 동시 작업자 수에 따라 실제 동시에 필요한 정렬 테이블수가 결정된다. 파티션은 작업자에 의해서 하나씩 선택되며 한 작업자가 작업을 완료하며 미 처리된 또 다른 파티션을 가지고 처리한다. 각 작업은 0 ~ N 파티션(한 파티션을 여러 작업자 공유하지는 않는다)을 구성한다. 0이 포함된 이유는 DOP > 파티션 수의 경우, 모든 작업자에게 파티션이 하나씩 돌아가지 않을 수도 있기 때문이다. 먼저 온 놈이 임자다 ^^

 

한 파티션을 여러 작업자가 공유하지 않으므로, 가장 큰 파티션에 병목이 발생할 수 있다. 다른 작업자는 모두 작업을 완료했지만 가장 정렬 작업자는 여전히 수행하고 있는 것이다. 더불어 해당 리소스(메모리 스레드 등)는 다른 쿼리에 의해서 재사용하지도 못한다.

 

마지막 단계의 짜집기도 필요 없다. 어차피 각 파티션이 분리된 b-tree에 해당하므로.

 

이것이 필요한 디스크 공간에 미치는 영향은:

-       사용자 데이터베이스에서 정렬하는 경우 각 파일 그룹별 2.2 x (파티션 크기)만큼을 요구한다.

-       tempdb를 사용한 경우 앞서의 직렬 처리에서의 이득을 동일하게 가질 수 없다. 병렬 처리이므로 동시에 여러 정렬 테이블을 처리해야 한다. 파티션 간의 데이터 실제 분포 정보를 모르는 한 2.2 x (인덱스 전체 크기)만큼의 여유 공간을 필요로 한다.

 

메모리 고려 사항

위에서 설명한 내용에 따라, 필요 메모리는 DOP수에 의존한다. ,

 

전체 메모리 = 40 x DOP + 추가 메모리

 

추가 메모리를 직렬/병렬 계획과는 무관하다.

 

 

다음 마지막 주제는,

시리즈-4. 정렬되지 않은 파티션 인덱스 구성

입니다. 또 기다려 주세요~~~

728x90

출처:http://blog.naver.com/mist80?Redirect=Log&logNo=40013039702

sp_makewebtask
실행된 쿼리에서 반환된 데이터가 들어 있는 HTML 문서를 작성하는 작업을 만듭니다.

을 이용하라~~  MSDN에서 sp_makewebtask 가믄 자세히 나온다...


2005의 경우 호환성을 위해 유지되나 Microsoft SQL Server 2005 Reporting Services(SSRS) 를 사용하여 새 웹 페이지를 보다 쉽게 만들 수 있습니다. (빠른 교체 권장)


그럼 한번 빠져 봅시다!!


사전 작업

1. 첨부한 파일을 다운 받아 C:\에 넣으세요.. 물론 다른곳에 하고 싶으면 알아서 ㅋㅋ

2. 만약 경로가 다르다면 쿼리상에서도 당근 변경해 주셔야 겠죠???


예제 시작

USE pubs


-- A. 템플릿 파일을 사용하여 여러 쿼리 만들기

EXECUTE sp_makewebtask
 @outputfile = 'C:\sp_makewebtask\MULTIPLE.HTM'
 , @query = ' SELECT title, price FROM titles
   SELECT au_lname, au_fname FROM authors
   SELECT pub_id, pub_name FROM publishers
   SELECT au_lname, au_fname FROM authors'
 , @templatefile = 'C:\sp_makewebtask\MULTIPLE.TPL'
 , @dbname = 'pubs',
 @rowcnt = 5,
 @whentype = 9
GO


-- 그럼 확인해 볼까요?? C:\sp_makewebtask로 이동하시면 MULTIPLE.HTM 파일 생겼죠?  신기 신기 ㅋㅋㅋ


-- B. 하이퍼링크 만들기
-- 테이블 생성
CREATE TABLE my_favorite_web_sites(url_def varchar(255), display_text varchar(255) NULL)
GO


-- 등록
INSERT my_favorite_web_sites(url_def, display_text)
VALUES ('http://www.microsoft.com', 'Microsoft Home Page')
INSERT my_favorite_web_sites(url_def) VALUES ('http://www.widgets.microsoft.com')
GO


-- 실행
EXECUTE sp_makewebtask
 @outputfile = 'C:\sp_makewebtask\URL.HTM'
 ,  @query='SELECT title, price FROM titles ORDER BY price desc'
 ,  @table_urls = 1
 , @tabborder = 0
 , @lastupdated=0
 , @colheaders = 0
 , @url_query= 'SELECT url_def, display_text FROM my_favorite_web_sites'
 , @whentype = 9
GO


-- 확인

-- URL.HTM 이라는 파일이 생겼죠? 실행 결과가 나오고... 링크도 걸린거 있죠???

@url_query  부분에 들어간 쿼리는 링크가 걸리는 거예용... 잘만 응용하믄 좋은 결과가 있을듯~~


-- C. 단일 행 모드로 여러 쿼리 실행
EXECUTE sp_makewebtask
   @outputfile = 'C:\sp_makewebtask\SROW.HTM'
 , @query = 'SELECT title, price FROM titles ORDER BY price desc
   SELECT au_lname, au_fname FROM authors WHERE state = ''CA'' '
 , @fixedfont = 0
 , @webpagetitle = 'Single row SQL Web Assistant'
 , @resultstitle = 'One row per page results'
 , @singlerow = 1
 , @rowcnt = 4
 , @URL = 'http://www.microsoft.com'
 , @reftext = 'Microsoft Home Page'
GO


-- 이번엔 Row 단위로 파일이 생겼습니다..

-- 참!! @rowcnt = 4로 주어기 때문에.. 파일이 8개 생겼죠?? 셀렉트문당 4개씩.. ^^

-- 이전 다음 버튼도 잇고 url로 추가해서 링크 걸수 있구용~~ 조아 조아~~


-- D. 데이터 삽입 표식 및 템플릿을 사용하여 여러 쿼리 실행
EXECUTE sp_makewebtask

 @outputfile = 'C:\sp_makewebtask\DATAINS.HTM'
 , @query = 'SELECT title, price FROM titles'
 , @templatefile = 'C:\sp_makewebtask\DATAINS.TPL'
 , @dbname = 'pubs'
 , @rowcnt = 10
 , @whentype = 9
 , @singlerow = 1
GO
-- @singlerow 를 0으로 하거나 지우면 한 파일에 생성되구용... 첫번째 결과랑 비슷하나.. 더욱 좋은 UI를 가져가고 싶다면 이번 방법이 좋겠죠???


MSDN에 나온 예제이구용...

잘만 응용하면 유용하게 쓰일듯 한뎁!! ㅋㅋ

728x90
글쓴이 : 김홍선


pivot 쿼리란 row의 형태로 주어지는 데이타를 column의 형태로 보여주는 쿼리이다.
예를 들어, 아래와 같이 scott.emp 테이블이 주어졌다고 하면,

EMPNO   ENAME    DEPTNO
-----------------------
7369    SMITH    20
7499    ALLEN    30
7521    WARD     30
7566    JONES    20
7654    MARTIN   30
7698    BLAKE    30
7782    CLARK    10
7788    SCOTT    20
7839    KING     10
7844    TURNER   30
7876    ADAMS    20
7900    JAMES    30
7902    FORD     20
7934    MILLER   10


위 테이블에서, 한 row는 해당 deptno에 속하는 한 명의 사원(employee)을 나타낸다.
이 테이블에서 각 deptno에 속하는 사원의 수를 다음과 같이 출력하고자 한다면,


DEPTNO_10  DEPTNO_20  DEPTNO_30
-------------------------------
3          5          6


쿼리를 아래와 같이 만들어 준다.


SELECT COUNT (DECODE (deptno, 10, 1)) deptno_10,
       COUNT (DECODE (deptno, 20, 1)) deptno_20,
       COUNT (DECODE (deptno, 30, 1)) deptno_30
  FROM emp


pivot 쿼리의 특징 중의 하나는 select 절에 count(decode(...)), sum(decode(...)), max(decode(...)) 등의 함수를 많이 쓴다는 것이다.





예제 추가)

아래와 같이 deptno 별로 clerk, salesman, manager의 수가 나타나도록 쿼리를 만들어보자.
(여기서도 emp 테이블을 사용한다.)



    DEPTNO      CLERK   SALESMAN    MANAGER
---------- ---------- ---------- ----------
        10          1          0          1
        20          2          0          1
        30          1          4          1


쿼리는 아래와 같다.


SELECT   deptno
       , COUNT (DECODE (job, 'CLERK', 1)) clerk
       , COUNT (DECODE (job, 'SALESMAN', 1)) salesman
       , COUNT (DECODE (job, 'MANAGER', 1)) manager
    FROM emp
GROUP BY deptno





위에서 예를 든 것과 같이 row 형태의 데이타를 column 형태로 보여주는 쿼리를 row-to-column pivot 쿼리라고 하고, 그 반대로 column 형태를 row 형태로 보여주는 쿼리를 column-to-row pivot 쿼리라고 하자.


column-to-row pivot 쿼리의 예는 아래 페이지에서 확인할 수 있다.
- http://www.soqool.com/servlet/board?cmd=view&cat=100&subcat=1010&seq=77

'데이터베이스 > SQL Server' 카테고리의 다른 글

퀴즈 문제  (0) 2008.04.29
DateTime ? Char(8) or (10)  (0) 2008.04.29
컬럼명 변경하기  (0) 2008.04.29
Table 변수 vs 임시 테이블 (Ver. 2000)  (0) 2008.04.29
SQL Server 2005의 XQuery 소개  (0) 2008.04.29

+ Recent posts