Làm cách nào để quản lý 3,1 tỷ hàng dữ liệu?


14

Tôi hiện đang được giao nhiệm vụ triển khai một lược đồ lưu trữ cho một lượng dữ liệu tương đối lớn. Dữ liệu chủ yếu sẽ được truy cập để xác định data pointgiá trị hiện tại , nhưng tôi cũng được yêu cầu theo dõi sáu tháng lịch sử để theo xu hướng / phân tích dữ liệu.

Một yêu cầu gần đây đã được thêm vào để theo dõi min/ max/ sumgiá trị trong một giờ qua.

LƯU Ý: Lý tưởng nhất là tôi muốn xem xét tùy chọn MongoDB, nhưng trước tiên tôi cần chứng minh rằng tôi đã sử dụng hết các tùy chọn SQL-Server.

Dữ liệu

Bảng sau đây biểu thị nguồn dữ liệu chính (được truy vấn thường xuyên nhất). Bảng sẽ có khoảng năm triệu hàng. Các thay đổi dữ liệu sẽ chủ yếu là các UPDATEcâu lệnh với các câu lệnh rất thường xuyên INSERTsau khi tải dữ liệu ban đầu. Tôi đã chọn phân cụm dữ liệu bởi dataPointIdvì bạn sẽ luôn luôn chọn all values for a given data point.

// Simplified Table
CREATE TABLE [dbo].[DataPointValue](
    [dataPointId]  [int] NOT NULL,
    [valueId]      [int] NOT NULL,
    [timestamp]    [datetime] NOT NULL,
    [minimum]      [decimal](18, 0) NOT NULL,
    [hourMinimum]  [decimal](18, 0) NOT NULL,
    [current]      [decimal](18, 0) NOT NULL,
    [currentTrend] [decimal](18, 0) NOT NULL,
    [hourMaximum]  [decimal](18, 0) NOT NULL,
    [maximum]      [decimal](18, 0) NOT NULL

    CONSTRAINT [PK_MeterDataPointValue] PRIMARY KEY CLUSTERED ([dataPointId],[valueId])
)

Bảng thứ hai lớn hơn đáng kể với khoảng 3,1 tỷ hàng (đại diện cho sáu tháng qua của dữ liệu). Dữ liệu cũ hơn sáu tháng sẽ bị thanh trừng; mặt khác, INSERTbáo cáo dữ liệu nghiêm ngặt (~ 200 hàng / giây, 720.000 hàng / giờ, 17 triệu hàng / tuần).

// Simplified Table
CREATE TABLE [dbo].[DataPointValueHistory](
    [dataPointId] [int]            NOT NULL,
    [valueId]     [int]            NOT NULL,
    [timestamp]   [datetime]       NOT NULL,
    [value]       [decimal](18, 0) NOT NULL,
    [delta]       [decimal](18, 0) NOT NULL

    CONSTRAINT [PK_MeterDataPointHistory] PRIMARY KEY CLUSTERED ([dataPointId], [valueId], [timestamp])

)

Kỳ vọng là bảng này sẽ tăng gấp đôi kích thước khi số lượng giá trị điểm dữ liệu được theo dõi tăng lên 400 hàng / giây (vì vậy đạt ~ 10 tỷ không phải là vấn đề).

(Các) Câu hỏi ( vâng, tôi đang hỏi nhiều hơn một ... chúng đều liên quan chặt chẽ với nhau).

Tôi hiện đang sử dụng cơ sở dữ liệu Phiên bản tiêu chuẩn SQL-Server 2008 R2. Tôi có thể sẽ thực hiện trường hợp nâng cấp lên Phiên bản doanh nghiệp nếu có thể đạt được mức hiệu suất mong muốn với các phân vùng bảng (hoặc MongoDB nếu không thể đạt các mức hiệu suất được yêu cầu với SQL-Server). Tôi muốn đầu vào của bạn về sau:


1) Cho rằng tôi cần tính toán min, maxsumtrong một giờ qua (như trong now - 60 minutes). Cách tiếp cận tốt nhất để theo dõi dữ liệu gần đây là gì:

  • Giữ dữ liệu gần đây trong bộ nhớ của dịch vụ dữ liệu. Viết ra tính toán tối thiểu / tối đa / trung bình với mỗi dữ liệu CẬP NHẬT.

  • Truy vấn lịch sử gần đây từ bảng lịch sử (tác động đến câu hỏi tiếp theo?) Trong mỗi câu lệnh CẬP NHẬT. Truy vấn sẽ truy cập dữ liệu mới nhất cho giá trị điểm dữ liệu và chỉ nên quét qua hàng triệu bản ghi gần nhất?

  • Lưu trữ lịch sử gần đây trong hàng DataPointValue để tránh tra cứu bảng lịch sử? Có lẽ được lưu trữ dưới dạng một chuỗi phân tách và được xử lý bên trong CẬP NHẬT?

  • Lựa chọn khác tôi chưa xem xét?


2) Đối với DataPointValueHistory, các truy vấn đối với dữ liệu sẽ luôn luôn bằng dataPointIdvà một hoặc nhiều valueId. Dữ liệu được truy vấn thường sẽ là cho ngày, tuần hoặc tháng cuối cùng, nhưng có thể là trong sáu tháng đầy đủ trong một số trường hợp.

Tôi hiện đang tạo một tập dữ liệu mẫu để thử nghiệm xem liệu có hợp lý hơn khi phân cụm theo dataPointId / valueId / timeStamp hoặc timeStamp / dataPointId / valueId. Nếu bất cứ ai có kinh nghiệm đối phó với một bảng có kích thước này và sẵn sàng cung cấp cái nhìn sâu sắc của họ, nó sẽ được đánh giá cao. Tôi nghiêng về tùy chọn thứ hai để tránh phân mảnh chỉ mục, nhưng hiệu năng truy vấn là rất quan trọng.

  • Phân cụm DataPointValueHistorytheo dataPointId -> valueId -> timeStamp

  • Phân cụm DataPointValueHistorytheo timeStamp -> dataPointId -> valueId


3) Cuối cùng, như đã đề cập ở trên, tôi nghĩ sẽ có ý nghĩa khi phân vùng DataPointValueHistorybảng. Bất kỳ đề xuất nào về cách phân vùng tốt nhất dữ liệu lịch sử sẽ được đánh giá rất cao.

  • Nếu được phân cụm theo dấu thời gian trước tiên, tôi nghĩ rằng dữ liệu nên được phân vùng theo tuần (tổng cộng 27 phân vùng). Phân vùng cũ nhất sẽ bị thanh trừng sau tuần 27.

  • Nếu được phân cụm bởi dataPointId trước tiên, tôi nghĩ rằng dữ liệu nên được phân vùng bởi một số mô-đun của id?

Vì tôi có kinh nghiệm rất hạn chế với phân vùng bảng, nên chuyên môn của bạn sẽ được đánh giá cao.


Bạn đã xóa phiên bản của câu hỏi này trên StackOverflow?
Taryn

@bluefeet - Vâng, nó được gắn cờ là ngoài chủ đề ... vì vậy tôi đã xóa câu hỏi SO và được tạo lại ở đây (có lẽ tôi nên đợi nó được di chuyển).
Calgary

Không có vấn đề gì, tôi chỉ đảm bảo rằng chúng tôi không có câu hỏi được đăng chéo.
Taryn

Trên Standard Edition, bạn vẫn có thể phân vùng dữ liệu bằng cách sử dụng các khung nhìn được phân vùng và nhiều bảng cơ sở. Không chắc chắn nếu bạn xem xét điều đó.
Jon Seigel

@Jon - Có, tôi đã xem xét các phân vùng bảng thủ công (sự lựa chọn cụ thể đó sẽ dựa trên việc có hay không có giấy phép Doanh nghiệp ... nếu có, tại sao lại đóng vai trò của riêng tôi).
Calgary

Câu trả lời:


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.