Cách tốt nhất để lưu trữ tất cả trừ năm hiện tại và phân vùng bảng cùng một lúc


23

Bài tập

Lưu trữ tất cả trừ một khoảng thời gian 13 tháng từ một nhóm các bảng lớn. Dữ liệu lưu trữ phải được lưu trữ trong cơ sở dữ liệu khác.

  • Cơ sở dữ liệu ở chế độ phục hồi đơn giản
  • Các bảng là 50 triệu hàng đến vài tỷ và trong một số trường hợp chiếm hàng trăm gb mỗi bảng.
  • Các bảng hiện không được phân vùng
  • Mỗi bảng có một chỉ mục được nhóm trên một cột ngày càng tăng
  • Mỗi bảng cũng có một chỉ mục không được nhóm
  • Tất cả các thay đổi dữ liệu cho các bảng được chèn
  • Mục tiêu là để giảm thiểu thời gian chết của cơ sở dữ liệu chính.
  • Máy chủ là 2008 R2 Enterprise

Bảng "lưu trữ" sẽ có khoảng 1,1 tỷ hàng, bảng "trực tiếp" khoảng 400 triệu. Rõ ràng bảng lưu trữ sẽ tăng theo thời gian, nhưng tôi hy vọng bảng trực tiếp cũng tăng nhanh một cách hợp lý. Nói ít nhất 50% trong vài năm tới.

Tôi đã nghĩ về cơ sở dữ liệu mở rộng Azure nhưng thật không may, chúng tôi đang ở 2008 R2 và có khả năng ở lại đó một thời gian.

Kế hoạch hiện tại

  • Tạo một cơ sở dữ liệu mới
  • Tạo các bảng mới được phân vùng theo tháng (sử dụng ngày sửa đổi) trong cơ sở dữ liệu mới.
  • Di chuyển 12-13 tháng gần đây nhất của dữ liệu vào các bảng được phân đoạn.
  • Thực hiện đổi tên hai cơ sở dữ liệu
  • Xóa dữ liệu đã di chuyển khỏi cơ sở dữ liệu "lưu trữ" hiện tại.
  • Phân vùng từng bảng trong cơ sở dữ liệu "lưu trữ".
  • Sử dụng hoán đổi phân vùng để lưu trữ dữ liệu trong tương lai.
    • Tôi nhận ra rằng tôi sẽ phải trao đổi dữ liệu sẽ được lưu trữ, sao chép bảng đó vào cơ sở dữ liệu lưu trữ và sau đó trao đổi nó vào bảng lưu trữ. Điều này được chấp nhận.

Vấn đề: Tôi đang cố gắng di chuyển dữ liệu vào các bảng được phân vùng ban đầu (thực tế tôi vẫn đang làm bằng chứng về khái niệm về nó). Tôi đang cố gắng sử dụng TF 610 (theo Hướng dẫn hiệu suất tải dữ liệu ) và một INSERT...SELECTtuyên bố để di chuyển dữ liệu ban đầu nghĩ rằng nó sẽ được ghi lại tối thiểu. Thật không may mỗi khi tôi thử nó đã đăng nhập đầy đủ.

Tại thời điểm này, tôi nghĩ rằng cách tốt nhất của tôi có thể là di chuyển dữ liệu bằng gói SSIS. Tôi đang cố gắng tránh điều đó vì tôi đang làm việc với 200 bảng và bất cứ điều gì tôi có thể làm theo kịch bản tôi có thể dễ dàng tạo và chạy.

Có bất cứ điều gì tôi thiếu trong kế hoạch chung của mình không và SSIS có phải là lựa chọn tốt nhất của tôi để di chuyển dữ liệu nhanh chóng và sử dụng tối thiểu nhật ký (mối quan tâm về không gian) không?

Mã demo không có dữ liệu

-- 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

Di chuyển mã

USE Audit_New
GO
DBCC TRACEON(610);

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

RE "di chuyển dữ liệu": Để ​​giảm thiểu việc sử dụng nhật ký, bạn có thể di chuyển dữ liệu theo đợt, ví dụ "Approch 2" trong dba.stackexchange.com/a/139009/94130 . Về chủ đề phân vùng bạn đã xem xét phân vùng xem chưa?
Alex

@Alex Yea, tôi đã xem xét cả hai. Kế hoạch dự phòng của tôi là di chuyển dữ liệu theo đợt bằng SSIS. Và trong trường hợp cụ thể này, vấn đề của tôi là chính xác phân vùng được xây dựng cho. (tải nhanh / hủy tải dữ liệu bằng cách sử dụng chuyển đổi)
Kenneth Fisher

Câu trả lời:


10

Tại sao bạn không nhận được đăng nhập tối thiểu?

Tôi đã tìm thấy Hướng dẫn hiệu suất tải dữ liệu mà bạn tham khảo là một tài nguyên cực kỳ quý giá. Tuy nhiên, nó cũng không toàn diện 100% và tôi nghi ngờ rằng lưới đã đủ phức tạp nên tác giả đã không thêm một cột Table Partitioningđể phá vỡ sự khác biệt trong hành vi tùy thuộc vào việc bảng nhận được chèn có được phân vùng hay không. Như chúng ta sẽ thấy sau đó, thực tế là bảng đã được phân vùng xuất hiện để ngăn chặn việc ghi nhật ký tối thiểu.

nhập mô tả hình ảnh ở đây

Phương pháp đề xuất

Dựa trên các đề xuất trong Hướng dẫn hiệu suất tải dữ liệu (bao gồm phần "Tải hàng loạt bảng được phân vùng") cũng như trải nghiệm tải các bảng được phân vùng với hàng chục tỷ hàng, đây là cách tiếp cận tôi muốn giới thiệu:

  • Tạo một cơ sở dữ liệu mới.
  • Tạo các bảng mới được phân vùng theo tháng trong cơ sở dữ liệu mới.
  • Di chuyển năm gần đây nhất của dữ liệu, theo cách sau:
    • Đối với mỗi tháng, tạo một bảng heap mới;
    • Chèn tháng dữ liệu đó vào heap bằng gợi ý TABLOCK;
    • Thêm chỉ mục được nhóm vào heap chứa tháng dữ liệu đó;
    • Thêm ràng buộc kiểm tra bắt buộc rằng bảng chỉ chứa dữ liệu của tháng này;
    • Chuyển bảng thành phân vùng tương ứng của bảng được phân vùng tổng thể mới.
  • Thực hiện đổi tên của hai cơ sở dữ liệu.
  • Cắt bớt dữ liệu trong cơ sở dữ liệu "lưu trữ".
  • Phân vùng từng bảng trong cơ sở dữ liệu "lưu trữ".
  • Sử dụng hoán đổi phân vùng để lưu trữ dữ liệu trong tương lai.

Sự khác biệt khi so sánh với cách tiếp cận ban đầu của bạn:

  • Phương pháp di chuyển 12-13 tháng dữ liệu gần đây sẽ hiệu quả hơn nhiều nếu bạn tải vào một đống với TABLOCKmột tháng một lần, sử dụng chuyển đổi phân vùng để đặt dữ liệu vào bảng được phân đoạn.
  • A DELETEđể xóa bảng cũ sẽ được ghi lại đầy đủ. Có lẽ bạn có thể TRUNCATEhoặc thả bảng và tạo bảng lưu trữ mới.

So sánh các phương pháp để di chuyển năm gần đây của dữ liệu

Để so sánh các cách tiếp cận trong một khoảng thời gian hợp lý trên máy của tôi, tôi đã sử dụng một 100MM rowbộ dữ liệu thử nghiệm mà tôi đã tạo và tuân theo lược đồ của bạn.

Như bạn có thể thấy từ các kết quả bên dưới, có sự tăng và giảm hiệu suất lớn trong ghi nhật ký bằng cách tải dữ liệu vào một đống bằng cách sử dụng TABLOCKgợi ý. Có một lợi ích bổ sung nếu điều này được thực hiện một phân vùng tại một thời điểm. Cũng đáng lưu ý rằng phương pháp một phân vùng một lần có thể dễ dàng được song song hóa hơn nữa nếu bạn chạy nhiều phân vùng cùng một lúc. Tùy thuộc vào phần cứng của bạn, điều đó có thể mang lại một sự gia tăng tốt đẹp; chúng tôi thường tải ít nhất bốn phân vùng cùng một lúc trên phần cứng lớp máy chủ.

nhập mô tả hình ảnh ở đây

Đây là kịch bản thử nghiệm đầy đủ .

Ghi chú cuối cùng

Tất cả những kết quả này phụ thuộc vào phần cứng của bạn ở một mức độ nào đó. Tuy nhiên, các thử nghiệm của tôi đã được tiến hành trên một máy tính xách tay lõi tứ tiêu chuẩn với ổ đĩa quay. Có khả năng tải dữ liệu sẽ nhanh hơn nhiều nếu bạn đang sử dụng một máy chủ đàng hoàng không có nhiều tải khác tại thời điểm bạn đang tiến hành quá trình này.

Ví dụ, tôi đã chạy phương pháp được đề xuất trên một máy chủ dev thực tế (Dell R720) và thấy giảm 76 seconds(từ 156 secondstrên máy tính xách tay của tôi). Thật thú vị, cách tiếp cận ban đầu của việc chèn vào một bảng được phân đoạn không gặp phải sự cải thiện tương tự và vẫn chỉ tiếp tục 12 minutestrên máy chủ dev. Có lẽ điều này là do mẫu này mang lại một kế hoạch thực hiện nối tiếp và một bộ xử lý trên máy tính xách tay của tôi có thể khớp với một bộ xử lý trên máy chủ dev.


Cảm ơn một lần nữa Geoff. Tôi đang sử dụng phương pháp SWITCH. Cụ thể tôi đang sử dụng SSIS & SQL động để chạy song song 13 tháng.
Kenneth Fisher

1

Đây có thể là một ứng cử viên tốt cho Biml. Một cách tiếp cận là tạo một mẫu có thể sử dụng lại để di chuyển dữ liệu cho một bảng trong phạm vi ngày nhỏ với một thùng chứa. Biml sẽ lặp qua bộ sưu tập bảng của bạn để tạo các gói giống hệt nhau cho mỗi bảng đủ điều kiện. Andy Leonard có một đoạn giới thiệu trong Stairway Series của mình .


0

Có thể, thay vì tạo cơ sở dữ liệu mới, hãy khôi phục cơ sở dữ liệu thực sang cơ sở dữ liệu mới và xóa dữ liệu mới nhất, 12-13 tháng. Sau đó, trong cơ sở dữ liệu thực của bạn xóa dữ liệu không có trong khu vực lưu trữ vừa tạo của bạn. Nếu xóa lớn là một vấn đề, có thể bạn chỉ cần xóa các bộ 10K hoặc lớn hơn bằng cách tập lệnh để thực hiện.

Các tác vụ phân vùng của bạn dường như không bị can thiệp và dường như có thể áp dụng cho cơ sở dữ liệu sau khi bạn xóa.


Tôi đã làm điều đó với cơ sở dữ liệu nhỏ hơn trước đây. Với kích thước hiện tại và thực tế là tôi muốn kết thúc với các bảng được phân vùng ở cả hai bên, tôi nghĩ phương pháp này thực sự sẽ tốn nhiều thời gian hơn và nhiều hơn một chút (gấp đôi kích thước DB hiện tại ở mức tối thiểu)
Kenneth Fisher
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.