Hyun Soo, Lim

가을에 진행된 PASS 2012 행사에서 소개된 신기능에 대해 소개드릴려고 합니다. 

프로젝트명 hekaton으로 불리는 신기능(인메모리 데이터베이스 엔진)이 SQL Server 차기 버전에 포함될 예정이라고 합니다.


그럼 지금까지 소개된 내용에 대해서 간략히 보도록 하겠습니다. 좀 더 자세한 내용이 궁금하신 분께서는 관련 링크를 참고해주세요.


0. Hekaton이란? (트랜잭션 처리를 빠르게 하기 위한 인메모리 데이터베이스 엔진)


1. Hekaton의 의미

   > 그리스어로 100

   > 데이터베이스를 100배 빠르게 향상시킨다는 의미 (가능한)


2. 설계 원칙

2-1. Optimize for main memory data access

   > 메인 메모리에 접근 빈도가 높은 테이블을 올려놓고 관리함. (ACID 만족시킴)

   > ACID를 보장하기 이해서 sequential IO가 발생함.

2-2. Accelerate business logic processing

   > Query와 Procedure를 컴파일하여 native code로 저장해놓아서 수행시 컴파일시간을 최적화함. (단축시킴)

2-3. Provide frictionless scale-up

   > Lock-free data structure를 사용하여 기존의 lock과 latch를 제거하여 높은 동시성을 제공

   > 하지만 데이터 일관성은 동일하게 보장

2-4. Built-in to SQL Server

   > SQL Server 차기버전에 포함된 기능

   > 프로그램 변경이 필요 없음.


3. 사용 예시

3-1. 테이블 생성

3-2. 프로시져 생성


4. 기타

   > xVelocity와 Hekaton은 둘 다 인메모리 기술이기는 하나 다른 목적을 가지고 있습니다. xVelocity의 경우 컬럼스토어, 파워피벗 등 BI/레포팅을 위한 기술이며, Hekaton의 경우 전통적인 데이터베이스 App에서 활용하기 위해서 설계된 row-based 기술입니다. (OLTP 환경에서 활용)


5. 참고 문헌

   > SQL Server vNext coming up with lot a new features|Hekaton, Polybase, PDW, and many more

   > SQL SERVER? What is Hekaton?? Simple Words Explanation

   > How Fast is Project Codenamed “Hekaton” ? It’s ‘Wicked Fast’

   > Hekaton? SQL Server’s in-memory database engine

   > Hekaton: In-Memory Transaction Processing Integrated with SQL Server

   > Breakthrough performance with in-memory technologies

   > Hekaton Query Acceleration Technology FAQs









 

SQL Server 2012 메모리 관리 부분에서 변경된 내용이 있어 간략히 정리하여 공유드립니다.

 

1. Memory Manager surface area changes in SQL Server 2012

1-1. 요약

    - 멀티페이지 관리 주체가 변경됨.

    - 메모리 관련 모니터링 항목의 기준 통일 (kb 단위)

    - NUMA 노드 메모리 관리나 추적이 좋아짐.

    - DMV 변경 사항 (원문 참고)

 

1-2. SQL Server 2008과 2012의 아키텍쳐 변경

         

 

2. Memory Manager Configuration changes in SQL Server 2012

2-1. 요약

    - Max server memory : 해당 항목이 관리하는 설정 범위가 변경됨

 

    - awe_enabled 옵션 제거

 

출처. 제목에 원본글 링크되어 있음.

 

대용량 데이터베이스를 복구하는 경우 현재 어떤 작업을 진행중인지 궁금해하면서 빨리 끝나기만을 기다리던 분들이 있을 것으로 생각합니다. 저 역시 그랬구요. 하지만 아래의 옵션을 사용하면 복구 진행과정 중 현재 어느 단계를 수행중인지/어느단계가 시간이 오래걸렸는지 바로 확인이 가능합니다.

[구문]

   DBCCTRACEON(3004, 3605,-1)


    - Trace
Flag 3004 : 백업 또는 복구 수행시 어떤 작업을 진행 중인지 상세히 로그를 보여줌

    - TraceFlag 3605 : SSMS에서 쿼리 수행시 결과창이 아니라 error log에 기록 

 
그럼 간단한 복구 테스트를 통해서 옵션 사용 유무에 따라서 얼마나 차이가 나는지 보도록 하겠습니다.

[테스트]
1. 복구 (옵션 비활성화)

-- 복구수행하기
restoredatabasetestdb_restoreFROM  DISK=N'E:\testdb_simple.bak'WITHfile= 1,
        moveN'testdb'toN'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\testdb_01.mdf',
        moveN'testdb_log'toN'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\testdb_log_01.ldf',
        moveN'Data01'toN'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\testdb_data_01.mdf',
        moveN'Data01_text'toN'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\testdb_data_text_01.mdf'

-- 에러로그 보기 (복구에 대한 기록은 5줄만 기록됨)
sp_readerrolog




2. 복구 (옵션 활성화)
-- Errorlog recycle
sp_cycle_errorlog

-- 옵션  활성화
DBCC TRACEON (3004, 3605, -1)

-- 복구수행하기
restore database testdb_restore_option FROM  DISK = N'E:\testdb_simple.bak' WITH file = 1,
        move N'testdb' to N'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\testdb_restore.mdf',
        move N'testdb_log' to N'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\testdb_restore_log.ldf',
        move N'Data01' to N'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\testdb_data_restore.mdf',
        move N'Data01_text' to N'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\testdb_data_text_restore.mdf'


-- 에러로그 보기 (복구에 대한 기록은 58줄 기록됨, 옵션 빈활성화에 비하여 약 11배이상 상세로그 기록됨)
sp_readerrolog




-- 옵션 비활성화
DBCC TRACEOFF (3004, 3605, -1)


[의견]
복구 절차 진행시 어디서 시간이 많이 소요되어지는 볼 수 있어 알아두면 도움이 될 것으로 보입니다.

[출처]What Is My Restore Doing?

SQL Server 2012에 신규로 추가된 Analytic Functions 중 LAG 함수 사용 사례를 보도록 하겠습니다.
조회시 데이터 레코드간에 편차를 보여주고 싶을 때 사용하시면 매우 유용한 기능입니다.

함수에 대한 간략히 설명드리고, SQL Server 2008 R2 이하 버전에서는 어떻게 쿼리 작성을 해서 사용했었는지와
함수 사용을 할 경우 성능차이가 있는지 테스트를 해보도록 하겠습니다.

[설명/문법]
1. 설명
 
    - LAG 함수란 동일한 레코드셋안에서 이전에 조회된 레코드에 포함된 값을 접근할 수 있도록 해줍니다. 
      SQL Server 2008 R2 이전 버전에서 동일한 결과를 만들기 위해서는 셀프조인을 활용해야 가능했습니다.

2.  문법 (상세내용은 온라인 도움말 참고)
    - LAG (scalar_expression [,offset] [,default]) OVER ( [partition_by_clause ] order_by_clause )

[테스트]
1. 테스트 환경 셋팅

-- 데이터베이스 생성

create database TESTDB 

use testdb
go

-- 임시 테이블 생성
-- drop table tab_01
create table Tab_01 (
    seqNo int identity(1,1)
,   compareValue int default 0);
go

create clustered index idx_Tab_01_seqNo on Tab_01 (seqNo)
go

-- 20개의 compareValue 랜덤값을 가지는 데이터 입력
insert into tab_01 (compareValue) values (rand()*1000)
go 20

-- 쿼리 성능 보기 위한 옵션 설정
set statistics io on
set statistics time on

2-1. LAG 함수 사용 (Case 1)
select
    seqNo
,   compareValue
,   lag(compareValue, 1, 0) over (order by seqNo) as LagValue
from tab_01 with (readuncommitted)
order by seqNo

-- 결과


-- 성능


-- 실행계획

2-2. 셀프 조인 사용_01 (Case 2, 순차적인 고유번호가 있는 경우)
select a.seqNo, a.CompareValue, b.CompareValue
from tab_01 a with (readuncommitted)
   
left outer join tab_01 b with (readuncommitted) on a.seqNo -1 = b.seqNo
order by a.seqNo

-- 결과


-- 성능


-- 실행계획


2-3. 셀프 조인 사용_02 (Case 3, 순차적인 고유번호가 없는 경우)
select a.seqNo, a.CompareValue, b.CompareValue
from
   
(
     select seqNo, CompareValue, rank() over (order by seqNo asc) RankNo
    
from tab_01 with (readuncommitted)
    )
a
    left outer join
   
(
     
select seqNo, CompareValue, rank() over (order by seqNo asc) RankNo
    
from tab_01 with (readuncommitted)
    )
b
    on a.RankNo -1 = b.RankNo
order by a.seqNo

-- 결과


-- 성능


-- 실행계획


3. 테스트 결과
    - 테스트 결과 IO 사용량의 차이는 아래와 같습니다. LAG 함수 사용이 이전 방식에 비하여 20배이상 성능이 좋은 것을 볼 수 있습니다.
      > Case 1. LAG 함수 사용 : 논리적인 읽기수 = 2
      > Case 2. 셀프 조인 사용_01 : 논리적인 읽기수 = 42
      > Case 3. 셀프 조인 사용_02 : 논리적인 읽기수 = 43

[의견]

    - LAG 함수를 사용하는 경우 조인을 하지 않아도 되기 때문에 읽기수 비용 절감율이 높다.
    - 다양한 활용/응용이 가능한 함수이기 때문에 참고에 적어놓은 아티클은 꼭 보시기를 권장해드리고 싶습니다.

[참고]
1. SQL Server 2012 온라인 도움말
2. SQL Server Mag - SQL Server 2012's Window Functions, Part 2 (Itzik Ben-Gan)

블로그 사이트에 가면 종종 볼 수 있는 기능인 "랜덤블로그 방문"을 DB에서 구현했던 사례를 소개드립니다.
기능에 대해서 설명드리면 "랜던길드" 버튼을 클릭하면 임의로 블로그를 선택해주는 것입니다.
해당 기능 중 여기서 테스트할 내용은 랜덤하게 블로그의 번호를 찾는 부분에 대해서 이야기하려고 합니다.
구현 방식에는 여러가지가 있겠지만 많이 사용하는 2가지 방식에 대한 테스트를 진행해보고 얼마나 성능 차이가
나는지에 대해서 보도록 하겠습니다.

1. 테스트 환경 구성

-- 테이

create table tbl_Blog (

        SeqNo          int            --

,       name           varchar(1000)  --

,       Contents       varchar(6000)  --

)

 

--

create clustered index idx_Article_seqNo on tbl_Blog (seqNo)

 

-- (6400)

insert into tbl_Blog (SeqNo, name, Contents)

select

        seqNo

,       replicate(seqNo, 50) as title

,       replicate(seqNo, 500) as contents

from (

        select

               row_number() over(order by a.name) as [seqNo]

        from sys.objects a

               cross join sys.objects b ) x

order by seqNo

 

-- 

set statistics io on

2. 테스트
2-1. 방법 1 : newid() 함수 사용

select top 1

        SeqNo

,       name

,       Contents

from (

        select

               seqNo

        ,       name

        ,       Contents

        ,       newid() as RandomID

        from tbl_Blog with (readuncommitted) ) x

order by RandomID


[결과]
-- 반복 실행해보시면 블로그번호가 계속 변경되어지는 것을 볼 수 있습니다.


-- 논리적인 읽기 수가 2048페이지로 높은 것을 볼 수 있습니다.

2-2. 방법 2 : rand() 함수 사용

declare @MaxSeqNo int

 

select top 1

        @MaxSeqNo = seqNo

from tbl_Blog with (readuncommitted)

order by SeqNo desc

 

select top 1

        seqNo

,       name

,       Contents

from tbl_Blog with (readuncommitted)

where SeqNo <= rand() *@MaxSeqNo

order by SeqNo desc


[결과]
-- 반복 실행해보시면 블로그번호가 계속 변경되어지는 것을 볼 수 있습니다.


-- 논리적인 읽기 수가 총 6으로 방법1에 비하여 매우 낮음을 볼 수 있습니다.


3. 의견
   > 조금만 응용하면 다양한 서비스에 활용이 가능합니다. (로터리 아이템 구현 등 랜덤이 들어가는 기능들...)
   > 새로운 기능 구현을 고려할 때 반드시 성능 부하가 높지 않을지 확인/검토하시기를 권장드립니다.












MSDB에 저장한 SSIS 패키지의 사용자 암호를 잊어버린 경우 쉽게 확인이 가능한 방법이 있어 공유드립니다.
이렇게 쉽게 확인이 가능하다는 것을 보니 살짝 걱정이 되기도 하네요.

그럼 진짜 가능한지 테스트를 진행해보도록 하겠습니다.

1. SSIS를 msdb에 저장하고, Job으로 등록합니다.
  

2.  Job 실행구문을 조회하면 암호를 그대로 볼 수 있습니다. (노랑색으로 표기한 부분이 암호)
SELECT sjs.command
FROM msdb.dbo.sysjobs sj    
     JOIN msdb.dbo.sysjobsteps sjs ON sj.job_id = sjs.job_id   
WHERE sj.name = 'TEST_SSIS'



3. 의견
   > 중요한 SSIS에 대해서 보안을 강화하기 위해서는 암호 방식을 사용하지 말아야 할 것 같네요.
   > SQL Server 2012의 SSIS는 처음 만들어보았는데, 많이 바뀌었네요. (확대기능도 있고, msdb 저장 메뉴도 변경됨)

출처. Tale of an Encrypted SSIS Package in msdb and a Lost Password

글을 보다가 재미난 테스트 내용이 있어 공유드립니다.

테스트 내용은 연결된 서버를 통해서 데이터를 가지고 올 때 Pull/Push(땡겨오는/밀어넣는) 방식에 따른
성능 차이가 얼마나 발생하는지 비교한 내용입니다.

1. 테스트 스크립트 (5만건의 데이터 이관할 때 사용한 스크립트)

-- Push Script

insertopenquery(SQL02,'select * from testDB.dbo.target_table')select*fromsource_table;

 

-- Pull Script

inserttarget_tableselect*fromopenquery(SQL01,'select * from testDB.dbo.test')

2. 테스트 결과


3. 결과에 대한 의견
  > Pull 방식이 Push 방식에 비해서 성능이 매우 좋은 것을 볼 수 있습니다. (약 120배)
  > 대량 데이터 이관시 Pull 방식을 사용하시기를 권장합니다.
  > 단순한 쿼리를 사용한 테스트이므로 모든 경우에 Push 방식이 더 빠르다고 이야기하기는 힘들 것 같습니다.
     (Join이나 subquery가 있는 경우 결과가 달라질 수 있지 않을까 생각해봅니다.)

4. 연결된 서버 사용에 대한 개인적인 의견
  > 서비스 프로시져 내에서 연결된 서버를 사용하는 것은 권장하고 싶지 않습니다.
     이유는 1대의 DB서버 장애시 다른 DB서버까지 장애가 확대되어지기 때문입니다.
  > 필요한 부분이나 상황에 맞추어 사용할 필요는 있지만 가능한 서비스 프로시져 내에서 여러 "연결된 서버"에
     접근하는 것은 제거 또는 최소화하는 것이 좋지 않을까합니다.


출처. Linked servers and performance impact: Direction matters!



SQL Server 언플러그 세미나 - 토크쇼 때 이야기나누었던 내용 간략히 정리하여 공유드립니다.

 

이야기드리고자 했던 내용은 아래와 같습니다.

  1. 고가용성 시스템 구축시 기술에 대한 깊이 있는 검토/테스트 필요 (장단점 비교 분석)

      - 안정성을 높이기 위한 기술인데 이로 인하여 문제가 발생하면 안되겠죠.~

  2. DB 시스템보다는 서비스 측면에서의 고민 필요

 

간략히 PT와 SQL Server 2012의 고가용 기능에 대한 테스트 동영상 올립니다.

 

[SQL Server 2012 AlwaysOn Availability Group]

 

 

 

 

 

 

정답은 당연히 "Database Snapshot의 데이터 변경은 당연히 불가능하다" 입니다. 
하지만 특정 경우에 대해서는 데이터 변경이 가능하여 이 부분에 대해서 소개드립니다.

길게 이야기할 필요 없이 바로 테스트를 진행해보도록 하겠습니다. 

1. 테스트 환경 셋팅

--@@ Orig 데이터베이스 생성

IF DB_ID('Orig') IS NOT NULL

        DROP DATABASE [Orig]

GO

 

CREATE DATABASE [Orig]

        ON PRIMARY ( NAME = N'Orig', FILENAME = N'D:\Orig.mdf')

GO

 

USE [Orig]

GO

 

IF OBJECT_ID('dbo.TestTable', 'U') IS NOT NULL

        DROP TABLE dbo.TestTable

GO

 

--@@ 사용자 테이블 생성

CREATE TABLE dbo.TestTable (Col1 int)

GO

 

IF OBJECT_ID('dbo.UpdView', 'V') IS NOT NULL

        DROP VIEW dbo.UpdView

GO

 

--@@ 생성

CREATE VIEW dbo.UpdView

AS

SELECT Col1

FROM Orig.dbo.TestTable   

GO

 

--@@ 테스트 데이터 입력

INSERT INTO dbo.TestTable (Col1) VALUES (1)

GO

 

IF DB_ID('Orig_Snapshot') IS NOT NULL

        DROP DATABASE [Orig_Snapshot]

GO

 

--@@ 스냅샷 생성

CREATE DATABASE [Orig_Snapshot]

        ON PRIMARY ( NAME = N'Orig', FILENAME = N'D:\Orig_Snapshot.ss') AS SNAPSHOT OF [Orig]   

GO



2. 테스트 진행

--@@ 스냅샷 데이터베이스로 이동

USE [Orig_Snapshot]

GO


--@@ 현재 데이터 확인

SELECT * FROM dbo.UpdView

GO
 

 

--@@ 데이터 입력

INSERT INTO dbo.UpdView VALUES (2), (3);
GO


--@@
데이터 변경

UPDATE dbo.UpdView SET Col1 = 99 WHERE Col1 = 3;
GO

 

--@@ 데이터 삭제

DELETE FROM dbo.UpdView

WHERE Col1 = 1;
GO

 

-- @@ 데이터 변경내용 조회

SELECT * FROM dbo.UpdView;

GO
 

3. 결론/의견
  > View 구문 내에 데이터베이스명을 적어준 부분으로 인하여 이러한 현상이 발생하는 것입니다.
     뷰를 만들 때 from 절에 데이터베이스명을 명시해주면 스냅샷 데이터베이스에서 뷰를 조회하더라도
     실제 DB에서 데이터를 가지고 옵니다. (당연히도)
  > 프로시져도 마찬가지로 동작할 것이기 때문에 스냅샷 데이터베이스를 사용할 경우 주의가 필요할 것 같습니다.
  > 잘 사용하면 스냅샷 데이터베이스 활용성을 높일 수 있는 반면에 이해가 없이 사용할 경우 문제가 되어질 수
     있으니 알아두시는 것이 좋을 듯 합니다.


출처. Successfully execute an INSERT, UPDATE and DELETE against a Database Snapshot


 

블로그를 보다가 재미있는 테스트 내용이 있어 공유드립니다.

SQL Server 2008에서 잘 사용하던 쿼리가 SQL Server 2012 CTP3에서 수행을 해보니 1803 에러가 발생해서
왜 그런지 조사를 해보았다는 내용입니다. 

설마 진짜 안되겠느냐라는 생각에 한번 해보았습니다. (2M 용량의 데이터베이스를 생성)
      

이유는 버전이 변경되어지면서 시스템 테이블이 추가되어지고, 변경되어지면서 데이터베이스 생성을 위한 기본용량이
더 커졌기 때문입니다.

상세한 내용에 대해서 궁금하신 분은 아래의 글 참고 부탁드립니다.


출처.
http://blogs.msdn.com/b/psssql/archive/2011/10/29/error-1803-and-model-size-change-in-sql-server-2012.aspx