Một vài đề xuất.Bạn có thể sẽ chạy các truy vấn tổng hợp về nội dung này, vì vậy sau (hoặc trong khi) bạn tải dữ liệu vào các bảng của mình, bạn nên tổng hợp trước dữ liệu, ví dụ như tổng số tính toán trước theo giờ hoặc theo người dùng, hoặc theo tuần, bất cứ điều gì, bạn có ý tưởng và lưu trữ nó trong các bảng bộ nhớ cache mà bạn sử dụng cho các biểu đồ báo cáo của mình. Nếu bạn có thể thu thập số liệu của mình theo thứ tự độ lớn thì tốt cho bạn!
Điều này có nghĩa là tôi sẽ lấy một số dữ liệu tại một khoảng thời gian bằng dấu thời gian.
Vì vậy, điều này có nghĩa là bạn chỉ sử dụng dữ liệu từ X ngày qua?
Xóa dữ liệu cũ khỏi bảng có thể chậm một cách khủng khiếp nếu bạn có vài chục triệu hàng để xóa, phân vùng rất tốt cho điều đó (chỉ cần thả phân vùng cũ). Nó cũng nhóm tất cả các bản ghi từ cùng một khoảng thời gian gần nhau trên đĩa sao cho nó hiệu quả hơn nhiều bộ nhớ cache.
Bây giờ nếu bạn sử dụng MySQL, tôi khuyên bạn nên sử dụng các bảng MyISAM. Bạn không nhận được sự chống va chạm hoặc giao dịch và khóa là câm, nhưng kích thước của bảng nhỏ hơn nhiều so với InnoDB, có nghĩa là nó có thể phù hợp với RAM, có nghĩa là truy cập nhanh hơn nhiều.
Vì các tập hợp lớn có thể liên quan đến rất nhiều IO đĩa tuần tự, một hệ thống IO nhanh như RAID10 (hoặc SSD) là một điểm cộng.
Có cách nào để tối ưu hóa bảng hoặc truy vấn để bạn có thể thực hiện các truy vấn này trong một khoảng thời gian hợp lý không?
Điều đó phụ thuộc vào bảng và truy vấn; không thể đưa ra lời khuyên nào mà không biết thêm.
Nếu bạn cần truy vấn báo cáo phức tạp với các tập hợp lớn và tham gia, hãy nhớ rằng MySQL không hỗ trợ bất kỳ JOINs ưa thích, hoặc hash-aggregates, hoặc bất cứ điều gì khác hữu ích thực sự, về cơ bản điều duy nhất nó có thể làm là là tốt trên một bảng lưu trữ, và hoàn toàn tàn bạo trên các trường hợp khác nếu một số truy cập ngẫu nhiên có liên quan.
Tôi đề nghị bạn nên kiểm tra với Postgres. Đối với tập hợp lớn, trình tối ưu hóa thông minh hơn hoạt động tốt.
Ví dụ:
CREATE TABLE t (id INTEGER PRIMARY KEY AUTO_INCREMENT, category INT NOT NULL, counter INT NOT NULL) ENGINE=MyISAM;
INSERT INTO t (category, counter) SELECT n%10, n&255 FROM serie;
(serie chứa đường 16M với n = 1 .. 16000000)
MySQL Postgres
58 s 100s INSERT
75s 51s CREATE INDEX on (category,id) (useless)
9.3s 5s SELECT category, sum(counter) FROM t GROUP BY category;
1.7s 0.5s SELECT category, sum(counter) FROM t WHERE id>15000000 GROUP BY category;
Trên một truy vấn đơn giản như pg đây là khoảng 2-3x nhanh hơn (chênh lệch sẽ lớn hơn nhiều nếu tham gia phức tạp có liên quan).