현재 연도를 제외하고 동시에 테이블을 분할하는 가장 좋은 방법은 무엇입니까?


23

태스크

큰 테이블 그룹에서 롤링 13 개월을 제외한 모든 것을 아카이브하십시오. 보관 된 데이터는 다른 데이터베이스에 저장해야합니다.

  • 데이터베이스가 단순 복구 모드입니다
  • 테이블은 5 천만 행에서 수십억 개이며 경우에 따라 각각 수백 GB를 차지합니다.
  • 테이블이 현재 파티션되지 않았습니다
  • 각 테이블에는 계속 증가하는 날짜 열에 하나의 클러스터형 인덱스가 있습니다.
  • 각 테이블에는 추가적으로 하나의 비 클러스터형 인덱스가 있습니다
  • 테이블에 대한 모든 데이터 변경 사항은 삽입입니다.
  • 목표는 기본 데이터베이스의 가동 중지 시간을 최소화하는 것입니다.
  • 서버는 2008 R2 Enterprise입니다

"보관"테이블에는 약 11 억 개의 행이 있고 "실제"테이블에는 약 4 억 개의 행이 있습니다. 분명히 아카이브 테이블은 시간이 지남에 따라 증가하지만 라이브 테이블도 합리적으로 빠르게 증가 할 것으로 기대합니다. 다음 몇 년 동안 50 % 이상이라고 말하십시오.

Azure 확장 데이터베이스에 대해 생각했지만 불행히도 우리는 2008 R2에 있으며 잠시 동안 머물러있을 것입니다.

현재 계획

  • 새로운 데이터베이스 생성
  • 새 데이터베이스에서 월별로 분할 된 새 테이블을 작성하십시오 (수정 된 날짜 사용).
  • 가장 최근 12-13 개월의 데이터를 파티션 된 테이블로 이동하십시오.
  • 두 데이터베이스의 이름 바꾸기 스왑을 수행하십시오.
  • 이제 "아카이브"데이터베이스에서 이동 된 데이터를 삭제하십시오.
  • "아카이브"데이터베이스에서 각 테이블을 파티션하십시오.
  • 파티션 스왑을 사용하여 나중에 데이터를 보관하십시오.
    • 보관할 데이터를 교체하고 해당 테이블을 보관 데이터베이스에 복사 한 다음 보관 테이블로 교체해야한다는 것을 알고 있습니다. 허용됩니다.

문제 : 데이터를 초기 분할 테이블로 옮기려고합니다 (사실 여전히 여전히 개념 증명을하고 있습니다). TF 610 ( Data Loading Performance Guide에 따라 )과 INSERT...SELECT최소한의 로그 기록을 생각하는 데이터를 이동 시키는 명령문을 사용하려고합니다. 불행히도 내가 시도 할 때마다 완전히 기록됩니다.

이 시점에서 SSIS 패키지를 사용하여 데이터를 이동하는 것이 최선의 방법이라고 생각합니다. 200 개의 테이블로 작업하고 스크립트로 할 수있는 모든 것을 쉽게 생성하고 실행할 수 있으므로 피하지 않으려 고합니다.

일반적인 계획에 빠진 것이 있습니까? 그리고 SSIS는 로그를 최소한으로 사용하고 데이터를 빠르게 이동하는 데 가장 좋은 방법입니다 (공간 문제)?

데이터가없는 데모 코드

-- Existing structure
USE [Audit]
GO

CREATE TABLE [dbo].[AuditTable](
    [Col1] [bigint] NULL,
    [Col2] [int] NULL,
    [Col3] [int] NULL,
    [Col4] [int] NULL,
    [Col5] [int] NULL,
    [Col6] [money] NULL,
    [Modified] [datetime] NULL,
    [ModifiedBy] [varchar](50) NULL,
    [ModifiedType] [char](1) NULL
); 
-- ~1.4 bill rows, ~20% in the last year

CREATE CLUSTERED INDEX [AuditTable_Modified] ON [dbo].[AuditTable]
(   [Modified] ASC   )
GO


-- New DB & Code
USE Audit_New
GO

CREATE PARTITION FUNCTION ThirteenMonthPartFunction (datetime)
AS RANGE RIGHT FOR VALUES ('20150701', '20150801', '20150901', '20151001', '20151101', '20151201', 
                            '20160101', '20160201', '20160301', '20160401', '20160501', '20160601', 
                            '20160701') 

CREATE PARTITION SCHEME ThirteenMonthPartScheme AS PARTITION ThirteenMonthPartFunction
ALL TO ( [PRIMARY] );

CREATE TABLE [dbo].[AuditTable](
    [Col1] [bigint] NULL,
    [Col2] [int] NULL,
    [Col3] [int] NULL,
    [Col4] [int] NULL,
    [Col5] [int] NULL,
    [Col6] [money] NULL,
    [Modified] [datetime] NULL,
    [ModifiedBy] [varchar](50) NULL,
    [ModifiedType] [char](1) NULL
) ON ThirteenMonthPartScheme (Modified)
GO

CREATE CLUSTERED INDEX [AuditTable_Modified] ON [dbo].[AuditTable]
(
    [Modified] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON ThirteenMonthPartScheme (Modified)
GO

CREATE NONCLUSTERED INDEX [AuditTable_Col1_Col2_Col3_Col4_Modified] ON [dbo].[AuditTable]
(
    [Col1] ASC,
    [Col2] ASC,
    [Col3] ASC,
    [Col4] ASC,
    [Modified] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON ThirteenMonthPartScheme (Modified)
GO

코드 이동

USE Audit_New
GO
DBCC TRACEON(610);

INSERT INTO AuditTable
SELECT * FROM Audit.dbo.AuditTable
WHERE Modified >= '6/1/2015'
ORDER BY Modified

RE "데이터 이동": 로그 사용을 최소화하기 위해 dba.stackexchange.com/a/139009/94130의 "Approch 2"와 같이 일괄 적으로 데이터를 이동할 수 있습니다 . 파티셔닝 주제에 대해 파티셔닝 된 뷰를 고려 했습니까?
Alex

@Alex Yea, 나는 그 두 가지를 모두 고려했습니다. 백업 계획은 SSIS를 사용하여 데이터를 일괄 적으로 이동하는 것입니다. 그리고이 특별한 경우 내 문제는 정확히 파티션이 만들어지는 것입니다. (스위칭을 사용한 빠른 데이터로드 / 언로드)
Kenneth Fisher

답변:


10

최소 로깅을받지 못하는 이유는 무엇입니까?

귀하가 참조 하는 Data Loading Performance Guide 가 매우 귀중한 리소스 라는 것을 알았습니다 . 그러나 100 % 포괄적이 아니며 그리드가 너무 복잡하여 작성자가 Table Partitioning삽입을 수신하는 테이블의 파티션 여부에 따라 동작의 차이를 나타 내기 위해 열 을 추가하지 않았을 것으로 생각합니다. 나중에 볼 수 있듯이 테이블이 이미 분할되어 있다는 사실은 최소한의 로깅을 방해하는 것으로 보입니다.

여기에 이미지 설명을 입력하십시오

권장 접근법

데이터로드 성능 안내서 ( "파티션 테이블 대량로드"섹션 포함)의 권장 사항과 수 천억 개의 행으로 파티션 된 테이블을로드 한 광범위한 경험을 바탕으로 다음과 같은 방법을 권장합니다.

  • 새 데이터베이스를 작성하십시오.
  • 새 데이터베이스에서 월별로 파티션 된 새 테이블을 작성하십시오.
  • 가장 최근의 데이터를 다음과 같은 방식으로 이동하십시오.
    • 매달 새 힙 테이블을 작성하십시오.
    • TABLOCK 힌트를 사용하여 해당 월의 데이터를 힙에 삽입하십시오.
    • 해당 월의 데이터를 포함하는 힙에 클러스터형 인덱스를 추가하십시오.
    • 테이블에 이번 달의 데이터 만 포함하도록하는 검사 제한 조건을 추가하십시오.
    • 테이블을 새로운 전체 파티션 테이블의 해당 파티션으로 전환하십시오.
  • 두 데이터베이스의 이름 바꾸기 스왑을 수행하십시오.
  • 이제 "아카이브"데이터베이스에서 데이터를 자릅니다.
  • "아카이브"데이터베이스에서 각 테이블을 파티션하십시오.
  • 파티션 스왑을 사용하여 나중에 데이터를 보관하십시오.

원래 접근 방식과 비교했을 때의 차이점 :

  • 최근 12-13 개월의 데이터를 이동하는 방법은 TABLOCK파티션 전환을 사용하여 데이터를 분할 된 테이블에 배치하여 한 번에 한 달에 한 번만 힙에로드하는 경우 훨씬 효율적 입니다.
  • DELETE오래된 테이블을 지우려면 A 가 완전히 기록됩니다. 아마 당신도 할 수 있습니다 TRUNCATE또는 테이블을 삭제하고 새로운 아카이브 테이블을 만듭니다.

최근 1 년간의 데이터 이동을위한 접근 방법 비교

내 컴퓨터에서 합리적인 시간 내에 접근 방식을 비교하기 위해 100MM row 내가 생성하고 스키마를 따르는 테스트 데이터 세트를 .

아래 결과에서 볼 수 있듯이 TABLOCK힌트를 사용하여 데이터를 힙에로드하면 성능이 크게 향상되고 로그 쓰기가 줄어 듭니다. 한 번에 하나의 파티션 만 수행하면 추가 이점이 있습니다. 한 번에 한 파티션 씩 방법을 여러 파티션을 한 번에 실행하면 쉽게 병렬화 할 수 있다는 점도 주목할 가치가 있습니다. 하드웨어에 따라 크게 향상 될 수 있습니다. 일반적으로 서버급 하드웨어에서 최소 4 개의 파티션을 한 번에로드합니다.

여기에 이미지 설명을 입력하십시오

전체 테스트 스크립트 는 다음과 같습니다 .

최종 노트

이러한 모든 결과는 어느 정도 하드웨어에 따라 다릅니다. 그러나 테스트는 회전 디스크 드라이브가 장착 된 표준 쿼드 코어 랩톱에서 수행되었습니다. 이 프로세스를 수행 할 때 다른로드가 많지 않은 괜찮은 서버를 사용하는 경우 데이터로드가 훨씬 빨라질 수 있습니다.

예를 들어 실제 dev 서버 (Dell R720)에서 권장되는 접근 방식을 실행하고 76 seconds( 156 seconds노트북에서) 축소되었습니다 . 흥미롭게도, 분할 된 테이블에 삽입하는 원래의 접근 방식은 동일한 향상을 경험하지 못했지만 여전히 12 minutesdev 서버에서 인계 받습니다. 이 패턴이 직렬 실행 계획을 생성하고 랩탑의 단일 프로세서가 개발자 서버의 단일 프로세서와 일치 할 수 있기 때문일 수 있습니다.


다시 한 번 감사드립니다. SWITCH 방법을 사용하고 있습니다. 특히 SSIS 및 동적 SQL을 사용하여 13 개월 동안 병렬로 실행하고 있습니다.
케네스 피셔

1

이것은 Biml의 좋은 후보가 될 수 있습니다. 한 가지 방법은 For Each 컨테이너를 사용하여 작은 날짜 범위의 단일 테이블에 대한 데이터를 마이그레이션하는 재사용 가능한 템플릿을 만드는 것입니다. Biml은 테이블 컬렉션을 반복하여 각 한정 테이블에 대해 동일한 패키지를 만듭니다. Andy Leonard는 그의 Stairway Series에 소개를했습니다 .


0

새 데이터베이스를 작성하는 대신 실제 데이터베이스를 새 데이터베이스로 복원하고 최신 12-13 개월 데이터를 삭제할 수 있습니다. 그런 다음 실제 데이터베이스에서 방금 만든 아카이브 영역에 포함되지 않은 데이터를 삭제하십시오. 큰 삭제가 문제가되는 경우 스크립트를 사용하여 10K 이상 세트를 삭제하면됩니다.

파티션 작업이 방해를받지 않는 것으로 보이며 삭제 후 두 데이터베이스 모두에 해당되는 것으로 보입니다.


전에는 더 작은 데이터베이스로 그 작업을 수행했습니다. 현재 크기와 나는이 방법은 실제로 (분에서 현재 DB의 크기를 두 배) 이상 및 상당히 더 많은 공간을 것 같아 양쪽에 분할 된 테이블로 끝날하려는 사실을 감안할 때
케네스 피셔
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.