Tạo 20.000 bảng là một ý tưởng tồi. Bạn sẽ cần 40.000 bảng trước đó và sau đó là nhiều hơn thế nữa.
Tôi đã gọi hội chứng này là Những rắc rối về siêu dữ liệu trong cuốn sách của tôi Phản vật chất SQL . Bạn thấy điều này xảy ra mỗi khi bạn định tạo "bảng trên X" hoặc "cột trên X".
Điều này gây ra các vấn đề về hiệu suất thực sự khi bạn có hàng chục nghìn bảng. Mỗi bảng yêu cầu MySQL duy trì cấu trúc dữ liệu nội bộ, bộ mô tả tệp, từ điển dữ liệu, v.v.
Ngoài ra còn có các hệ quả hoạt động thực tế. Bạn có thực sự muốn tạo một hệ thống yêu cầu bạn tạo một bảng mới mỗi khi người dùng mới đăng ký không?
Thay vào đó, tôi khuyên bạn nên sử dụng Phân vùng MySQL .
Đây là một ví dụ về phân vùng bảng:
CREATE TABLE statistics (
id INT AUTO_INCREMENT NOT NULL,
user_id INT NOT NULL,
PRIMARY KEY (id, user_id)
) PARTITION BY HASH(user_id) PARTITIONS 101;
Điều này mang lại cho bạn lợi ích khi xác định một bảng logic, đồng thời chia bảng thành nhiều bảng vật lý để truy cập nhanh hơn khi bạn truy vấn giá trị cụ thể của khóa phân vùng.
Ví dụ:Khi bạn chạy một truy vấn như ví dụ của mình, MySQL chỉ truy cập vào phân vùng chính xác có chứa user_id cụ thể:
mysql> EXPLAIN PARTITIONS SELECT * FROM statistics WHERE user_id = 1\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: statistics
partitions: p1 <--- this shows it touches only one partition
type: index
possible_keys: NULL
key: PRIMARY
key_len: 8
ref: NULL
rows: 2
Extra: Using where; Using index
Phương pháp phân vùng HASH có nghĩa là các hàng được đặt trong một phân vùng theo mô-đun của khóa phân vùng số nguyên. Điều này có nghĩa là nhiều user_id ánh xạ đến cùng một phân vùng, nhưng mỗi phân vùng sẽ chỉ có 1 / N số hàng trung bình (trong đó N là số phân vùng). Và bạn xác định bảng với số lượng phân vùng không đổi, vì vậy bạn không phải mở rộng bảng mỗi khi có người dùng mới.
Bạn có thể chọn bất kỳ số lượng phân vùng nào lên đến 1024 (hoặc 8192 trong MySQL 5.6), nhưng một số người đã báo cáo các vấn đề về hiệu suất khi chúng lên cao đến mức đó.
Nên sử dụng một số phân vùng nguyên tố. Trong trường hợp các giá trị user_id của bạn tuân theo một mẫu (chẳng hạn như chỉ sử dụng số chẵn), việc sử dụng số nguyên tố của phân vùng sẽ giúp phân phối dữ liệu đồng đều hơn.
Trả lời câu hỏi của bạn trong bình luận:
Đối với phân vùng HASH, nếu bạn sử dụng 101 phân vùng như tôi trình bày trong ví dụ trên, thì bất kỳ phân vùng nhất định nào cũng có trung bình khoảng 1% số hàng của bạn. Bạn cho biết bảng thống kê của bạn có 30 triệu hàng, vì vậy nếu bạn sử dụng cách phân vùng này, bạn sẽ chỉ có 300 nghìn hàng cho mỗi phân vùng. Điều đó dễ dàng hơn nhiều cho MySQL để đọc qua. Bạn cũng có thể (và nên) sử dụng các chỉ mục - mỗi phân vùng sẽ có chỉ mục riêng và nó sẽ chỉ lớn bằng 1% so với chỉ mục trên toàn bộ bảng không được phân vùng.
Vì vậy, câu trả lời cho cách bạn có thể xác định số lượng phân vùng hợp lý là:toàn bộ bảng của bạn lớn bao nhiêu và bạn muốn trung bình các phân vùng lớn bao nhiêu?
Số lượng phân vùng không nhất thiết phải tăng lên nếu bạn sử dụng phân vùng HASH. Cuối cùng, bạn có thể có tổng cộng 30 tỷ hàng, nhưng tôi nhận thấy rằng khi khối lượng dữ liệu của bạn tăng theo thứ tự độ lớn, điều đó vẫn đòi hỏi một kiến trúc mới. Nếu dữ liệu của bạn lớn như vậy, bạn có thể cần sharding qua nhiều máy chủ cũng như phân vùng thành nhiều bảng.
Điều đó nói rằng, bạn có thể phân vùng lại bảng bằng ALTER TABLE:
ALTER TABLE statistics PARTITION BY HASH(user_id) PARTITIONS 401;
Việc này phải cấu trúc lại bảng (giống như hầu hết các thay đổi ALTER TABLE), vì vậy, có thể mất một chút thời gian.
Bạn có thể muốn theo dõi kích thước của dữ liệu và chỉ mục trong các phân vùng:
SELECT table_schema, table_name, table_rows, data_length, index_length
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE partition_method IS NOT NULL;
Giống như với bất kỳ bảng nào, bạn muốn tổng kích thước của các chỉ mục hoạt động vừa với vùng đệm của mình, bởi vì nếu MySQL phải hoán đổi các phần của chỉ mục trong và ngoài vùng đệm trong khi truy vấn SELECT, thì hiệu suất sẽ bị ảnh hưởng.
Nếu bạn sử dụng phân vùng RANGE hoặc LIST, thì việc thêm, bớt, hợp nhất và chia nhỏ các phân vùng phổ biến hơn nhiều. Xem http://dev.mysql. com / doc / refman / 5.6 / en / partitioning-management-range-list.html
Tôi khuyến khích bạn đọc phần thủ công về phân vùng và cũng có thể xem bản trình bày hay này: Tăng hiệu suất Với các phân vùng MySQL 5.1 .