Bạn nên đọc phần sau và tìm hiểu một chút về ưu điểm của bảng innodb được thiết kế tốt và cách tốt nhất để sử dụng các chỉ mục được phân nhóm - chỉ khả dụng với innodb!
http://dev.mysql.com/doc /refman/5.0/en/innodb-index-types.html
http:// www. xaprb.com/blog/2006/07/04/how-to-exploit-mysql-index-optimizations/
sau đó thiết kế hệ thống của bạn một cái gì đó theo dòng của ví dụ đơn giản sau:
Lược đồ mẫu (đơn giản hóa)
Các tính năng quan trọng là các bảng sử dụng công cụ innodb và khóa chính cho bảng chủ đề không còn là một khóa auto_increoring đơn lẻ mà là một cụm tổng hợp dựa trên sự kết hợp của forum_id và thread_id. ví dụ:
threads - primary key (forum_id, thread_id)
forum_id thread_id
======== =========
1 1
1 2
1 3
1 ...
1 2058300
2 1
2 2
2 3
2 ...
2 2352141
...
Mỗi hàng diễn đàn bao gồm một bộ đếm được gọi là next_thread_id (unsigned int) được duy trì bởi một trình kích hoạt và tăng lên mỗi khi một chủ đề được thêm vào một diễn đàn nhất định. Điều này cũng có nghĩa là chúng tôi có thể lưu trữ 4 tỷ chủ đề trên mỗi diễn đàn thay vì tổng cộng 4 tỷ chủ đề nếu sử dụng một khóa chính auto_increment duy nhất cho thread_id.
forum_id title next_thread_id
======== ===== ==============
1 forum 1 2058300
2 forum 2 2352141
3 forum 3 2482805
4 forum 4 3740957
...
64 forum 64 3243097
65 forum 65 15000000 -- ooh a big one
66 forum 66 5038900
67 forum 67 4449764
...
247 forum 247 0 -- still loading data for half the forums !
248 forum 248 0
249 forum 249 0
250 forum 250 0
Nhược điểm của việc sử dụng khóa tổng hợp là bạn không còn có thể chỉ chọn một chủ đề bằng một giá trị khóa duy nhất như sau:
select * from threads where thread_id = y;
bạn phải làm:
select * from threads where forum_id = x and thread_id = y;
Tuy nhiên, mã ứng dụng của bạn nên biết người dùng đang duyệt diễn đàn nào để không khó thực hiện chính xác - lưu trữ forum_id hiện đang xem trong trường biến phiên hoặc trường biểu mẫu ẩn, v.v.
Đây là giản đồ đơn giản:
drop table if exists forums;
create table forums
(
forum_id smallint unsigned not null auto_increment primary key,
title varchar(255) unique not null,
next_thread_id int unsigned not null default 0 -- count of threads in each forum
)engine=innodb;
drop table if exists threads;
create table threads
(
forum_id smallint unsigned not null,
thread_id int unsigned not null default 0,
reply_count int unsigned not null default 0,
hash char(32) not null,
created_date datetime not null,
primary key (forum_id, thread_id, reply_count) -- composite clustered index
)engine=innodb;
delimiter #
create trigger threads_before_ins_trig before insert on threads
for each row
begin
declare v_id int unsigned default 0;
select next_thread_id + 1 into v_id from forums where forum_id = new.forum_id;
set new.thread_id = v_id;
update forums set next_thread_id = v_id where forum_id = new.forum_id;
end#
delimiter ;
Bạn có thể nhận thấy rằng tôi đã bao gồm reply_count như một phần của khóa chính, điều này hơi kỳ lạ vì bản thân tổ hợp (forum_id, thread_id) là duy nhất. Đây chỉ là một tối ưu hóa chỉ mục giúp tiết kiệm một số I / O khi các truy vấn sử dụng reply_count được thực thi. Vui lòng tham khảo 2 liên kết ở trên để biết thêm thông tin về điều này.
Truy vấn mẫu
Tôi vẫn đang tải dữ liệu vào các bảng mẫu của mình và cho đến nay tôi đã tải được khoảng. 500 triệu hàng (nhiều hơn một nửa so với hệ thống của bạn). Khi quá trình tải hoàn tất, tôi dự kiến sẽ có khoảng:
250 forums * 5 million threads = 1250 000 000 (1.2 billion rows)
Tôi đã cố tình tạo một số diễn đàn chứa hơn 5 triệu chủ đề, ví dụ, diễn đàn 65 có 15 triệu chủ đề:
forum_id title next_thread_id
======== ===== ==============
65 forum 65 15000000 -- ooh a big one
Thời gian chạy truy vấn
select sum(next_thread_id) from forums;
sum(next_thread_id)
===================
539,155,433 (500 million threads so far and still growing...)
dưới innodb, việc tổng hợp next_thread_ids để đưa ra tổng số luồng nhanh hơn nhiều so với thông thường:
select count(*) from threads;
Diễn đàn 65 có bao nhiêu chủ đề:
select next_thread_id from forums where forum_id = 65
next_thread_id
==============
15,000,000 (15 million)
một lần nữa, điều này nhanh hơn bình thường:
select count(*) from threads where forum_id = 65
Được rồi, bây giờ chúng ta biết rằng chúng ta có khoảng 500 triệu chủ đề cho đến nay và diễn đàn 65 có 15 triệu chủ đề - hãy xem lược đồ hoạt động như thế nào :)
select forum_id, thread_id from threads where forum_id = 65 and reply_count > 64 order by thread_id desc limit 32;
runtime = 0.022 secs
select forum_id, thread_id from threads where forum_id = 65 and reply_count > 1 order by thread_id desc limit 10000, 100;
runtime = 0.027 secs
Tôi trông khá hiệu quả - vì vậy đó là một bảng duy nhất có hơn 500 triệu hàng (và đang tăng lên) với truy vấn bao gồm 15 triệu hàng trong 0,02 giây (khi đang tải!)
Tối ưu hơn nữa
Chúng sẽ bao gồm:
-
phân vùng theo phạm vi
-
sharding
-
ném tiền và phần cứng vào nó
vv ...
hy vọng bạn thấy câu trả lời này hữu ích :)