Anda harus membaca yang berikut dan belajar sedikit tentang keuntungan dari tabel innodb yang dirancang dengan baik dan cara terbaik untuk menggunakan indeks berkerumun - hanya tersedia dengan 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/
lalu rancang sistem Anda seperti contoh sederhana berikut:
Contoh skema (disederhanakan)
Fitur penting adalah bahwa tabel menggunakan mesin innodb dan kunci utama untuk tabel utas tidak lagi menjadi kunci auto_incrementing tunggal tetapi gabungan berkelompok kunci berdasarkan kombinasi forum_id dan thread_id. misalnya
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
...
Setiap baris forum menyertakan penghitung yang disebut next_thread_id (unsigned int) yang dikelola oleh pemicu dan bertambah setiap kali utas ditambahkan ke forum tertentu. Ini juga berarti kami dapat menyimpan 4 miliar utas per forum daripada total 4 miliar utas jika menggunakan satu kunci utama peningkatan otomatis untuk id_utas.
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
Kerugian menggunakan kunci komposit adalah Anda tidak bisa lagi hanya memilih utas dengan satu nilai kunci sebagai berikut:
select * from threads where thread_id = y;
yang harus kamu lakukan:
select * from threads where forum_id = x and thread_id = y;
Namun, kode aplikasi Anda harus mengetahui forum mana yang dijelajahi pengguna sehingga tidak terlalu sulit untuk diterapkan - simpan forum_id yang saat ini dilihat dalam variabel sesi atau bidang formulir tersembunyi, dll...
Berikut skema yang disederhanakan:
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 ;
Anda mungkin telah memperhatikan saya telah memasukkan reply_count sebagai bagian dari kunci utama yang agak aneh karena komposit (forum_id, thread_id) itu sendiri unik. Ini hanyalah pengoptimalan indeks yang menyimpan beberapa I/O saat kueri yang menggunakan reply_count dieksekusi. Silakan merujuk ke 2 tautan di atas untuk info lebih lanjut tentang ini.
Contoh kueri
Saya masih memuat data ke dalam tabel contoh saya dan sejauh ini saya telah memuat kira-kira. 500 juta baris (setengah dari sistem Anda). Ketika proses pemuatan selesai, saya akan mengharapkan kira-kira:
250 forums * 5 million threads = 1250 000 000 (1.2 billion rows)
Saya sengaja membuat beberapa forum berisi lebih dari 5 juta utas misalnya, forum 65 memiliki 15 juta utas:
forum_id title next_thread_id
======== ===== ==============
65 forum 65 15000000 -- ooh a big one
Waktu proses kueri
select sum(next_thread_id) from forums;
sum(next_thread_id)
===================
539,155,433 (500 million threads so far and still growing...)
di bawah innodb menjumlahkan next_thread_ids untuk memberikan jumlah total utas jauh lebih cepat dari biasanya:
select count(*) from threads;
Berapa banyak utas yang dimiliki forum 65:
select next_thread_id from forums where forum_id = 65
next_thread_id
==============
15,000,000 (15 million)
sekali lagi ini lebih cepat dari biasanya:
select count(*) from threads where forum_id = 65
Ok sekarang kita tahu kita memiliki sekitar 500 juta utas sejauh ini dan forum 65 memiliki 15 juta utas - mari kita lihat bagaimana kinerja skema :)
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
Terlihat cukup berkinerja bagi saya - jadi itu satu tabel dengan 500+ juta baris (dan terus bertambah) dengan kueri yang mencakup 15 juta baris dalam 0,02 detik (saat dimuat!)
Pengoptimalan lebih lanjut
Ini akan mencakup:
-
partisi berdasarkan rentang
-
membagi
-
membuang uang dan perangkat keras ke dalamnya
dll...
semoga jawaban ini bermanfaat :)