Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

MySQL dan NoSQL:Bantu saya memilih yang tepat

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 :)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Apakah akan menggunakan SET NAMA

  2. Pisahkan nilai dari satu bidang menjadi dua

  3. MySQL - Cara memilih data berdasarkan panjang string

  4. Bagaimana cara mengelompokkan berdasarkan minggu di MySQL?

  5. Bagaimana cara menghindari kata-kata yang dicadangkan yang digunakan sebagai nama kolom? MySQL/Buat Tabel