Đọc nhanh mà không phải trả giá khi viết


7

Chúng tôi có một bảng phụ lục lớn chỉ chứa các giao dịch tài chính. Trung bình 1000 giao dịch được chèn mỗi phút. Vì hiện nay ngày càng có nhiều usecase chúng tôi thực sự muốn đọc, tìm kiếm và tổng hợp các giao dịch này, nên đọc nhanh sẽ rất hay.

Chúng tôi muốn đảm bảo ghi rất nhanh và thêm chỉ mục để bao quát một số bài đọc sẽ làm chậm việc ghi.

Tin tốt là chúng ta có thể đủ khả năng dữ liệu cũ. Tôi đã xem xét để tạo một bản sao dữ liệu vào bảng được tối ưu hóa đọc (có chỉ mục) mỗi n phút, điều này cũng cho phép sao chép hàng loạt định kỳ (do đó hạn chế số lượng ops?)

Tôi đang tìm kiếm một ý kiến ​​về việc đây có phải là một chiến lược hợp lệ hay không. Nếu bạn coi đây là một chiến lược hợp lý, bạn có con trỏ tùy chọn thực hiện không? Nếu không, các lựa chọn thay thế là gì?


4
Phiên bản và phiên bản của SQL Server là gì Tôi đoán Luôn luôn có thể là một giải pháp ở đây Nếu tôi đọc chính xác câu hỏi của bạn.
Shanky

Bạn có nhớ đăng bảng và nơi bạn muốn lập chỉ mục. Theo giao dịch với bạn, nghĩa là phần chèn được gói trong giao dịch SQL hoặc đó là một "giao dịch tài chính" được thể hiện bằng một dòng duy nhất.
paparazzo

Câu trả lời:


6

Đối với SQL Server 2014 và sau đó, khuyến nghị của tôi khá triệt để: chuyển sang một chỉ mục cửa hàng cột. 1000 bản ghi / phút cũng nằm trong phạm vi khả năng tải hàng loạt của cột, trên phần cứng thậm chí còn khiêm tốn. Xem Chỉ mục kho lưu trữ cụm: Tối ưu hóa tải dữ liệu - Ghi nhật ký tối thiểuSQL Server phân cụm cột Tuple Mover . Các hiệu suất truy vấn của một columnstore clustered khá loạng choạng do những lợi thế vốn có dung lượng lưu trữ hình cây cột và xử lý hàng loạt. Nhưng thậm chí nhiều hơn theo chuỗi thời gian (mà dữ liệu của bạn có thể là), do rất có khả năng loại bỏ phân khúc .

Trên SQL Server 2016, có một số cải tiến cụ thể nhắm mục tiêu vào trường hợp của bạn, hãy xem Phân tích hoạt động theo thời gian thực bằng Công nghệ trong bộ nhớtăng tốc phân tích kinh doanh bằng công nghệ trong bộ nhớ .

Đối với SQL Server 2012 trở về trước, khuyến nghị của tôi là nâng cấp lên 2014 hoặc 2016.

Trong mọi trường hợp, tôi sẽ né tránh Sao chép giao dịch, vì hai lý do:

Ngoài ra, cần phải xem xét rằng vận chuyển nhật ký hoặc các phần thứ hai luôn có thể đọc được chỉ có thể giảm tải cho việc xử lý truy vấn, nhưng không phải là các yêu cầu lược đồ (ví dụ: chỉ mục). Bất kỳ chỉ mục nào được yêu cầu bằng cách truy vấn trên bản sao sẽ phải được tạo trên DB gốc và giá được trả tại thời điểm ghi.

Tất nhiên tôi giả sử bạn đã siêng năng và bài viết của bạn được tối ưu hóa ngay bây giờ, tức là. tất cả các lời khuyên trong Hướng dẫn hiệu suất tải dữ liệu được áp dụng và tải lên của bạn là hàng loạt và được ghi lại tối thiểu.


4
Lưu ý điều này giả định Doanh nghiệp
Aaron Bertrand

Tôi đã đọc nó và vẫn còn một số việc phải làm, và điều này có vẻ rất phù hợp, nhưng hiện tại chúng tôi chỉ có giấy phép phiên bản Tiêu chuẩn và giấy phép Doanh nghiệp khá đắt: - /
JefClaes

Để có ngân sách, bạn có thể dùng thử luồng Hadoop Hivetruy vấn Hive
Remus Rusanu

1
Nhưng vào cuối ngày, 16 lần chèn mỗi giây không có gì đáng lo ngại về việc "các chỉ mục sẽ làm chậm việc ghi".
Remus Rusanu

2

Không đề cập đến các khả năng phần cứng và giải pháp HA rõ ràng, tôi sẽ xem xét việc xây dựng một "bảng phân tầng" được lập chỉ mục tối thiểu hoặc thậm chí là một đống, nơi bạn có thể giảm tải các giao dịch đến với hiệu suất tối đa.

Sau đó, một quy trình được lên lịch / định kỳ có thể di chuyển không đồng bộ dữ liệu đó vào bảng thực tế chính, có thể có các chỉ mục phù hợp hơn để báo cáo. Quá trình tương tự cũng có thể duy trì các tổng hợp trong một bảng khác, vì vậy bạn có thể xây dựng các báo cáo trực tiếp trên các tổng hợp đó. Khóa này không đồng bộ , vì vậy tôi sẽ không sử dụng các kích hoạt hoặc các khung nhìn được lập chỉ mục, mà là một cái gì đó giống như một công việc của Đại lý máy chủ SQL chạy một thủ tục được lưu trữ nhiều lần.

Ưu điểm:

  • Chèn cực nhanh (hầu như không có thời gian chờ đợi nào khi viết giao dịch)
  • Số lượng hàng lớn hơn được chèn cho mỗi lô trong bảng thực tế, sẽ cung cấp hiệu suất ghi tốt hơn
  • Cho phép tốt hơn / nhiều chỉ mục hơn trên bảng thực tế
  • Các bảng tổng hợp sẽ cung cấp hiệu suất báo cáo khá tốt

Nhược điểm:

  • Bảng phân tầng có thể bị khóa trong một thời gian ngắn khi được thăm dò bởi quy trình không đồng bộ.
  • Độ trễ nhẹ từ khi chèn cho đến khi dữ liệu có sẵn.
  • Thêm phức tạp

Ồ, và nếu bạn đang dùng SQL Server 2014/2016 Enterprise Edition, bảng phân tầng của bạn có thể nằm trong bộ nhớ.


Đối với quy trình không đồng bộ, hãy xem xét cdc vì nó chạy khỏi nhật ký giao dịch, do đó không khóa bảng phân tầng của bạn (sau đó bạn có thể thêm chỉ mục vào bảng cdc để tối ưu hóa số lần đọc)
Andrew Bickerton

2

Nếu đó chỉ là một bảng duy nhất, hãy nghĩ về ý tưởng có một bản sao thứ hai của bảng được sử dụng chỉ cho mục đích báo cáo. Tôi đã viết một loạt hai phần về giải pháp của tôi ở đây: Phần 1 | Phần 2 .

Về cơ bản, bạn có một bảng biểu thị một bản sao của bảng giao dịch của bạn, nhưng nó được tối ưu hóa cho khối lượng công việc báo cáo của bạn (như vậy, có lẽ nó chỉ có một tập hợp con của các cột, một tập hợp con của các hàng và một phần của quy trình đó có thể tạo ra hoàn toàn khác nhau các chỉ mục trên bản sao đã đọc của bảng - mặc dù điều đó sẽ thêm thời gian vào quy trình).

Mỗi N phút, một cái gì đó ít hơn bất cứ thứ gì phản ánh định nghĩa của bạn về "cũ", bạn điền một bản sao thứ hai của bảng này (trong một lược đồ khác hoặc với một tên khác) với dữ liệu mới hơn từ bảng giao dịch của bạn. Khi nó được điền, bạn có thể bắt đầu giao dịch, trao đổi các bảng (tên hoặc lược đồ) và sau đó cam kết. Người tiếp theo đọc dữ liệu từ bản sao sẽ nhận được dữ liệu tươi hơn.

Thời gian tải nền lười biếng mất bao lâu không thực sự quan trọng, vì bạn đã thừa nhận rằng dữ liệu cũ là ổn. Tuy nhiên, bạn phải chắc chắn liên kết các quyền với cả hai bản sao và thống kê cũng có thể cần phải là một phần của quy trình.


1

1000 giao dịch mỗi phút
= 16,67 / giây
= 480.000 / 8 giờ ngày

16,67 / giây không phải là nhanh. Tôi nhận được hơn 100 / giây trên một bảng lớn hoạt động bình thường.

Chọn PK của bạn hoặc ít nhất một chỉ mục mà bạn có thể sắp xếp dữ liệu đến để bạn có sự phân mảnh tối thiểu của chỉ mục đó.

Nếu bạn có thể giữ các bản ghi để chèn 100 hoặc 1000 cùng một lúc và chèn chúng được sắp xếp. Một lần chèn 100 bản ghi nhanh hơn nhiều so với 100 lần chèn mỗi bản ghi. Có bộ đếm thời gian mà chúng được chèn ít nhất mỗi x giây.

Trên các chỉ mục khác chỉ chọn những gì bạn cần. Cung cấp cho họ hệ số lấp đầy như 50. Bạn sẽ ngạc nhiên khi thấy sự phân mảnh chậm hơn xảy ra nếu bạn để lại một khoảng trống với hệ số lấp đầy.

Thực hiện bảo trì chỉ số hàng ngày.

Có bạn rất có thể cần phải trở nên kỳ lạ hơn nhưng 1000 / phút không phải là lớn. Ngay cả khi bạn có được thiết kế chỉ số kỳ lạ hơn mà giảm thiểu phân mảnh vẫn là một điều tốt.


1

Tôi nghĩ rằng câu trả lời của Daniel có lẽ tốt hơn của tôi, nhưng chỉ để cung cấp cho bạn các lựa chọn thay thế cơ bản:

Sao chép giao dịch chỉ với bảng đó được sao chép, đến một máy chủ khác.

Ưu điểm:

  • Dữ liệu tức thì, dễ đọc
  • Khóa đọc sẽ chỉ chặn máy chủ nhân rộng
  • Sao chép giao dịch được đọc thông qua nhật ký giao dịch của bạn, với một Đại lý đọc tất cả các giao dịch, tạo ra một tập lệnh được gửi đến cơ sở dữ liệu phân phối

Nhược điểm:

  • Chèn tất cả dữ liệu dưới dạng Row-By-Row vào cơ sở dữ liệu sao chép của bạn (chậm)
  • Yêu cầu một cá thể / máy chủ mới
  • Yêu cầu nhiều thời gian bảo trì / DBA hơn, cùng với các bước bổ sung để khôi phục (tạo ảnh chụp nhanh mới, v.v.)
  • Chi phí hoạt động thêm của việc duy trì cơ sở dữ liệu phân phối
  • Độ trễ mạng sẽ gây ra độ trễ sao chép, khiến cơ sở dữ liệu nhân rộng hơi lỗi thời

Nhật ký vận chuyển (Cơ sở dữ liệu thứ cấp đang nhận nhật ký giao dịch phải ở trạng thái chờ để cho phép đọc)

Ưu điểm:

  • Tất cả các bảng được khôi phục thành công sang phiên bản mới, cho phép các truy vấn của bạn đạt được bất kỳ bảng nào
  • Không ảnh hưởng đến máy chủ chính

Nhược điểm:

  • Kích thước của cơ sở dữ liệu đích sẽ luôn bằng cơ sở dữ liệu chính
  • Lưu lượng truy cập mạng, nếu được gửi ngoài trang web
  • Người dùng sẽ được khởi động khi nhật ký được khôi phục

Như đã nêu ở trên trong một câu trả lời khác, Log Shipping không thể thực sự phục vụ mục đích này. Bảng vận chuyển sẽ có lược đồ giống hệt với bảng gốc và người đăng ban đầu muốn các chỉ mục khác nhau trong bảng "cũ" của mình. Nhật ký vận chuyển sẽ yêu cầu các chỉ mục đó cũng nằm trong bảng "trực tiếp".
Ross Presser

1

Bạn có cần phải xử lý điều này trực tiếp trong cơ sở dữ liệu? Quan điểm của tôi, vì bạn ổn với dữ liệu hơi cũ, là lưu trữ các kết quả truy vấn riêng lẻ, thay vì toàn bộ bảng, trong một lớp như memcached hoặc redis .

Đây là một cách tiếp cận khá chuẩn trong phát triển ứng dụng web. Nhược điểm chính là nó đòi hỏi nỗ lực phát triển trên ứng dụng, có thể không hoạt động cho tình huống cụ thể của bạn (nhưng chúng tôi không biết được những gì bạn đã nói với chúng tô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.