Database/MSSQL Server

Partition Truncate Table

데이터엔지니어 주형권 2017. 4. 14. 14:36
반응형

들어가며

SQL Server 2016 부터 파티션 단위로 Truncate가 가능 합니다. 


다음의 블로그를 참고하여, 만들었으며 2016 기능을 사용해 보고자 포스트를 작성하였습니다.

참고 : https://www.mssqltips.com/sqlservertip/4436/sql-server-2016-truncate-table-with-partitions/


위의 블로그의 경우 Partition 테이블의 최대 장점이 스트라이프로 데이터를 넣는 것이므로, NDF 파일과 파일그룹을 여러개 생성해서 만들고 있는데요.

이 부분은 제외하고, 단순히 파티션만 나눠서 Truncate 하는 부분만 포스팅 하고자 합니다. (기능만 보면 되므로) 

제가 알기로 대용량의 DB를 관리 할 경우 테이블을 일자 또는 월별로 쪼개서 각각 파일그룹과 NDF를 생성하여, 기간이 일정 부분 지나면, 삭제하는 식으로 운영 하였다면

이 Partition Truncate를 통하여, 한 테이블에 넣고 그냥 해당 파티션만 Truncate 날려버리면 되므로 운영 포인트가 많이 줄어 들게 될 것 같습니다. 



시나리오


Step 1 

파일그룹 및 NDF 파일 생성 - 파티션용으로 새롭게 만듭니다.

USE [master]

GO

-- 파일 그룹 생성

ALTER DATABASE [TEST] ADD FILEGROUP [PARTITON_GROUP]

GO

 

-- NDF파일 생성

ALTER DATABASE [TEST] ADD FILE ( NAME = N'PARTITION', FILENAME = N'C:\MSSQL_DATA\PARTITION_GROUP.ndf' , SIZE = 4096KB , FILEGROWTH = 1024KB ) TO FILEGROUP [PARTITON_GROUP]

GO


Step 2

파티션 함수 및 파티션 스키마 생성 

USE TEST

GO

CREATE PARTITION FUNCTION PARTITION_FN(DATETIME) AS

  RANGE RIGHT FOR VALUES

  ('2017-01-01')

GO

 

 

CREATE PARTITION SCHEME PARTITION_SH AS

  PARTITION PARTITION_FN  TO

  (

   [PARTITON_GROUP],

   [PRIMARY] )

GO


Step 3

테이블 생성 - 파티션 스키마 명을 기재하고, 어떤 값을 기준으로 나눌 것인지 명시 합니다.

USE TEST

GO

 

CREATE TABLE TEST_Partition

(

 USERID                INT

,Name                  VARCHAR(20)

,Reg_date              DATETIME

)ON PARTITION_SH (Reg_date)

GO


Step 4

파티션이 정상적으로 생성되었는지 확인

SELECT  table_name             = object_name(PT.object_id)

        ,       index_name             = IDX.name

        ,       part_schema            = PS.name

        ,       part_function  = PF.name

        ,       boundary               = CASE WHEN PF.boundary_value_on_right = 1 THEN 'Right(<)' ELSE 'Left(=<)' END

        ,       boundary_value = ISNULL(CONVERT(nvarchar(100),RV.value,121),N'LargePartition')

        ,       PT.rows

        ,       AU.total_pages

        ,       AU.used_pages

        ,       PT.*

  FROM                 sys.allocation_units   AS AU

 INNER  JOIN    sys.partitions                AS PT

                              ON      AU.container_id = PT.partition_id

 INNER  JOIN    sys.indexes                           AS IDX

                              ON      PT.object_id   = IDX.object_id

                              AND     PT.index_id            = IDX.index_id

 INNER  JOIN    sys.partition_schemes  AS PS

                              ON      PS.data_space_id = IDX.data_space_id

  LEFT  JOIN    sys.partition_functions       AS PF

                              ON      PS.function_id = PS.function_id

  LEFT  JOIN    sys.partition_range_values    AS RV

                              ON      RV.function_id = PF.function_id

                              AND     RV.boundary_id = PT.partition_number

 WHERE  PT.object_id = object_id('TEST_Partition')


Step 5 

아래의 스크린샷을 보면, 둘 다 Rows가 0으로 표시 됩니다. 현재 파티션에 들어있는 row가 없기 때문입니다.


3개의 INSERT를 통해서, 데이터를 넣어보겠습니다.

INSERT INTO TEST_Partition VALUES (1,'주형권01','2017-01-03 02:03')

INSERT INTO TEST_Partition VALUES (2,'주형권02','2016-12-03 02:03')

INSERT INTO TEST_Partition VALUES (6,'주형권03','2018-12-03 02:03')

위의 Rows를 보시면 증가했음을 보실 수 있습니다. 부등호에 의해서 2016년도 날짜로 표기된 데이터만 파티션에 들어가고, 나머지는 LargePartition에 들어갑니다.

현재가 2017-04-14일 이므로, 2016년도 데이터가 필요 없다고 판단되어, 2017-01-01 이전의 데이터를 Truncate 시켜야 한다고 가정 하면 다음과 같이 합니다.


Step 6

파티션 Truncate 로 데이터 삭제 

- 아래의 Truncate 구문에서 어떤 파티션을 지울 것인지 지정하는 곳이 있습니다. 이것은 위의 파티션 테이블을 조회하는 쿼리에서 partition_Number로 조회 가능 합니다.

TRUNCATE TABLE TEST_Partition WITH (PARTITIONS (1));

GO


현재 보면 Partiotion_number가 1인 2017-01-01 이전의 데이터는 row가 0건 입니다.


실제로 데이터는 조회하면, 우리가 지우고자 했던 데이터만 지워졌음을 볼 수 있습니다. 

이는 Truncate 테이블이 모든 데이터를 지우는 것에 비해 Partition Truncate는 지정된 파티션만 삭제 함을 알 수 있습니다.




그 밖에...


1. 파티션 Truncate 는 여러개의 Partition을 삭제 가능 합니다. 범위로 Ttruncate 됩니다. 아래와 같이 지정해주시면 됩니다. 

TRUNCATE TABLE PartitionDemo2016 WITH (PARTITIONS (2 TO 3));

GO


반응형