Một câu trả lời điên rồ theo nghĩa đen, nhưng nếu bạn có một loại hệ thống sao chép nào đó được thiết lập (đối với một hệ thống có hàng tỷ hàng, tôi hy vọng bạn làm như vậy), bạn có thể sử dụng công cụ ước tính sơ bộ (như MAX(pk)
), chia giá trị đó cho số nô lệ bạn có, chạy một số truy vấn song song.
Đối với hầu hết các phần, bạn sẽ phân vùng các truy vấn trên các nô lệ dựa trên khóa tốt nhất (hoặc khóa chính tôi đoán), theo cách đó (chúng tôi sẽ sử dụng 250000000 làm Hàng / nô lệ của chúng tôi):
-- First slave
SELECT COUNT(pk) FROM t WHERE pk < 250000000
-- Ith slave where 2 <= I <= N - 1
SELECT COUNT(pk) FROM t WHERE pk >= I*250000000 and pk < (I+1)*250000000
-- Last slave
SELECT COUNT(pk) FROM t WHERE pk > (N-1)*250000000
Nhưng bạn chỉ cần SQL. Thật là một bức tượng bán thân. Ok, vì vậy hãy nói rằng bạn là một người buồn bã. Trên chủ (hoặc nô lệ gần nhất) rất có thể bạn cần tạo một bảng cho việc này:
CREATE TABLE counter_table (minpk integer, maxpk integer, cnt integer, slaveid integer)
Vì vậy, thay vì chỉ có các lựa chọn chạy trong nô lệ của bạn, bạn sẽ phải thực hiện thao tác chèn, giống như sau:
INSERT INTO counter_table VALUES (I*25000000, (I+1)*250000000, (SELECT COUNT(pk) FROM ... ), @@SLAVE_ID)
Bạn có thể gặp vấn đề với nô lệ viết lên bàn trên chủ. Bạn có thể cần nhận được nhiều hơn nữa - ý tôi là, sáng tạo:
-- A table per slave!
INSERT INTO counter_table_slave_I VALUES (...)
Cuối cùng, bạn nên có một nô lệ tồn tại cuối cùng trong đường dẫn đi ngang qua biểu đồ nhân rộng, liên quan đến nô lệ đầu tiên. Nô lệ đó bây giờ nên có tất cả các giá trị truy cập khác và nên có các giá trị riêng. Nhưng vào thời điểm bạn hoàn thành, có thể có các hàng được thêm vào, vì vậy bạn phải chèn một hàng khác bù cho pk tối đa được ghi trong counter_table của bạn và pk tối đa hiện tại.
Tại thời điểm đó, bạn phải thực hiện một hàm tổng hợp để tìm ra tổng số hàng là gì, nhưng điều đó dễ dàng hơn vì bạn sẽ chạy nó trên hầu hết các "số nô lệ bạn có và thay đổi".
Nếu bạn đang ở trong tình huống bạn có các bảng riêng biệt trong các nô lệ, bạn có thể UNION
lấy tất cả các hàng bạn cần.
SELECT SUM(cnt) FROM (
SELECT * FROM counter_table_slave_1
UNION
SELECT * FROM counter_table_slave_2
UNION
...
)
Hoặc bạn biết, hãy bớt điên rồ hơn một chút và di chuyển dữ liệu của bạn sang hệ thống xử lý phân tán hoặc có thể sử dụng giải pháp Kho dữ liệu (điều này cũng sẽ cung cấp cho bạn dữ liệu tuyệt vời trong tương lai).
Xin lưu ý, điều này phụ thuộc vào mức độ sao chép của bạn được thiết lập. Vì nút cổ chai chính rất có thể sẽ là lưu trữ liên tục, nếu bạn có bộ lưu trữ hỗn độn hoặc kho lưu trữ dữ liệu bị phân tách kém với tiếng ồn hàng xóm nặng nề, điều này có thể sẽ khiến bạn chạy chậm hơn chỉ chờ một lần duy nhấtSELECT COUNT(*) ...
Nhưng nếu bạn có bản sao tốt, thì tốc độ tăng của bạn sẽ liên quan trực tiếp đến số lượng hoặc nô lệ. Trên thực tế, nếu chỉ mất 10 phút để chạy truy vấn đếm một mình và bạn có 8 nô lệ, bạn sẽ cắt thời gian của mình xuống dưới một vài phút. Có lẽ một giờ để giải quyết các chi tiết của giải pháp này.
Tất nhiên, bạn sẽ không bao giờ thực sự nhận được câu trả lời chính xác đáng kinh ngạc vì cách giải quyết phân tán này giới thiệu một chút thời gian nơi các hàng có thể bị xóa và chèn, nhưng bạn có thể thử lấy một khóa hàng phân tán cùng một lúc và có được số đếm chính xác của các hàng trong bảng trong một thời điểm cụ thể.
Trên thực tế, điều này dường như là không thể, vì về cơ bản bạn bị mắc kẹt với một giải pháp chỉ dành cho SQL và tôi không nghĩ rằng bạn đã cung cấp một cơ chế để chạy một truy vấn bị khóa và bị khóa trên nhiều nô lệ, ngay lập tức. Có thể nếu bạn có quyền kiểm soát tệp nhật ký sao chép ... điều đó có nghĩa là bạn thực sự đang quay cuồng nô lệ cho mục đích này, điều này chắc chắn sẽ chậm hơn so với việc chỉ chạy truy vấn đếm trên một máy.
Vì vậy, có hai đồng xu 2013 của tôi.