Saya sedang mengerjakan aplikasi yang melibatkan banyak penulisan basis data, kira-kira ~ 70% sisipan dan 30% dibaca. Rasio ini juga akan mencakup pembaruan yang saya anggap satu baca dan satu tulis. Melalui pernyataan penyisipan, beberapa klien memasukkan data ke dalam basis data melalui pernyataan menyisipkan di bawah ini:
$mysqli->prepare("INSERT INTO `track` (user, uniq_name, ad_name, ad_delay_time ) values (?, ?, ?, ?)");
Pertanyaannya adalah apakah saya harus menggunakan insert_delay atau menggunakan mekanisme mysqli_multi_query karena pernyataan insert menggunakan ~ 100% cpu di server. Saya menggunakan mesin InnoDB pada database saya sehingga memasukkan yang tertunda tidak mungkin. Penyisipan di server ~ 36k / jam dan 99,89% dibaca, saya juga menggunakan pernyataan pilih di sana mengambil data tujuh kali dalam permintaan tunggal , permintaan ini membutuhkan 150 detik pada server untuk mengeksekusi. Teknik atau mekanisme apa yang bisa saya gunakan untuk tugas ini? Memori server saya adalah 2 gb, apakah saya harus menambah memori? Lihat masalah ini, setiap saran akan berterima kasih kepada saya.
Struktur meja:
+-----------------+--------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+-------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user | varchar(100) | NO | | NULL | |
| uniq_name | varchar(200) | NO | | NULL | |
| ad_name | varchar(200) | NO | | NULL | |
| ad_delay_time | int(11) | NO | | NULL | |
| track_time | timestamp | NO | MUL | CURRENT_TIMESTAMP | |
+-----------------+--------------+------+-----+-------------------+----------------+
Basis data status saya, ini menunjukkan 41k penyisipan (menulis), yang sangat lambat untuk database saya.
SHOW FULL PROCESSLIST
saat mengambil 100% cpu? Berapa banyak koneksi yang Anda izinkan vs berapa banyak yang diambil selama waktu ini?SHOW GLOBAL VARIABLES LIKE 'innodb%';
danSELECT VERSION();
dan tampilkan hasilnya.Jawaban:
Karena Anda memiliki lebih banyak tulisan daripada membaca, saya ingin merekomendasikan yang berikut ini
Penyesuaian yang layak dari InnoDB akan menjadi kuncinya
Buffer Pool ( Diukuran oleh innodb_buffer_pool_size )
Karena InnoDB tidak mendukung INSERT DELAYED , menggunakan Pool Buffer InnoDB besar adalah hal terdekat yang dapat Anda peroleh dengan INSERT DELAYED. Semua DML (INSERT, UPDATE, dan DELETE) akan di-cache di Pool Buffer InnoDB. Informasi transaksional untuk Menulis ditulis segera ke Redo Logs (ib_logfile0, ib_logfile1). Tulisan yang diposting di Buffer Pool secara berkala memerah dari memori ke disk melalui ibdata1 (InsertBuffer untuk Secondary Indexes, Double Write Buffer). Semakin besar Buffer Pool, semakin besar jumlah INSERT yang bisa di-cache. Dalam sistem dengan 8GB atau lebih dari RAM, gunakan 75-80% dari RAM sebagai innodb_buffer_pool_size. Dalam sistem dengan RAM yang sangat sedikit, 25% (untuk mengakomodasi OS).
CAVEAT: Anda dapat mengatur innodb_doublewrite menjadi 0 untuk mempercepat menulis lebih banyak, tetapi dengan risiko integritas data. Anda juga dapat mempercepat dengan menyetel innodb_flush_method ke O_DIRECT untuk mencegah caching InnoDB ke OS.
Redo Logs ( Diukuran oleh innodb_log_file_size )
Secara default, redo log diberi nama ib_logfile0 dan ib_logfile1 dan masing-masing akan berukuran 5MB. Ukurannya harus 25% dari innodb_buffer_pool_size. Jika redo log sudah ada, tambahkan pengaturan baru di my.cnf, matikan mysql, hapus, dan restart mysql .
Buffer Log ( Diukuran oleh innodb_log_buffer_size )
Buffer log menyimpan perubahan dalam RAM sebelum memasukkannya ke dalam redo log. Standarnya adalah 8M. Semakin besar buffer log, semakin sedikit Disk I / O. Hati-hati dengan transaksi yang sangat besar, karena ini dapat memperlambat KOMIT dalam milidetik.
Mengakses Banyak CPU
MySQL 5.5 dan MySQL 5.1 InnoDB Plugin memiliki pengaturan agar InnoDB Storage Engine mengakses beberapa CPU. Berikut adalah opsi yang perlu Anda atur:
Tingkatkan ke MySQL 5.5
Jika Anda memiliki MySQL 5.0, tingkatkan ke MySQL 5.5. Jika Anda memiliki MySQL 5.1.37 atau sebelumnya, tingkatkan ke MySQL 5.5. Jika Anda memiliki MySQL 5.1.38 atau lebih dan ingin tetap di MySQL 5.1, instal Plugin InnoDB. Dengan begitu, Anda dapat memanfaatkan semua CPU untuk InnoDB.
sumber
INT (2) masih menggunakan 4 byte - mungkin maksud Anda TINYINT UNSIGNED?
Berapa banyak nilai yang berbeda di setno? Jika kecil, KUNCI (setno) tidak akan pernah digunakan. INSERTing harus memperbarui indeks itu; menghapus KUNCI akan mempercepat MASUKKAN beberapa.
CHAR (10) - Apakah
flag
selalu 10 karakter? Dan di utf8? Mungkin Anda bisa menggunakan flag VARCHAR (10) CHARACTER SET asciiBatch sisipan Anda - 100 sekaligus akan berjalan 10 kali lebih cepat. (Melampaui 100 masuk ke 'pengembalian berkurang'.)
Berapa nilai autocommit? Apakah Anda membungkus setiap INSERT dalam BEGIN ... COMMIT? Berapa nilai innodb_flush_log_at_trx_commit?
sumber
code
masukkan ke nilai t_name (col1, col2, col3) (val1, val2, val3), (val1, val2, val3), (val1, val2, val3), (val1, val2, val3), (val1, val2, val3);code
Siapkan antrian. Aplikasi akan menulis ke dalam antrian 1 baris sekaligus dan kemudian mengambil baris keluar dan memasukkan ke dalam basis data dalam jumlah berdasarkan jumlah baris pada jumlah waktu yang berlalu sejak memasukkan terakhir.
Saya telah melihat di mana mengumpulkan 10.000 sisipan sekaligus adalah yang tercepat, jadi Anda perlu menguji untuk menemukan sweet spot.
Anda bisa membuat sistem antrian sederhana sendiri atau menggunakan yang sudah ada. Berikut adalah beberapa contoh: HornetQ dan File :: Queue . Berikut adalah posting di SE yang mencantumkan beberapa opsi bagus lainnya: Antrian pesan dalam perl, php, python .
sumber