Menyisipkan ke tabel berikut ini membutuhkan waktu hingga 70 detik untuk menyelesaikan:
CREATE TABLE IF NOT EXISTS `productsCategories` (
`categoriesId` int(11) NOT NULL,
`productsId` int(11) NOT NULL,
PRIMARY KEY (`categoriesId`,`productsId`),
KEY `categoriesId` (`categoriesId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Ada sekitar 100.000 baris dalam tabel, dan itu mengambil 7MB pada disk.
Apakah ada beberapa pengaturan di MySQL yang dapat meningkatkan kinerja penulisan?
my.cnf
File saya adalah sebagai berikut:
log-slow-queries="/var/log/mysql/slow-query.log"
long_query_time=1
log-queries-not-using-indexes
innodb_buffer_pool_size=4G
innodb_log_buffer_size=4M
innodb_flush_log_at_trx_commit=2
innodb_thread_concurrency=8
innodb_flush_method=O_DIRECT
query_cache_size = 6G
key_buffer_size = 284M
query_cache_limit = 1024M
thread_cache_size = 128
table_cache = 12800
sort_buffer_size=2M
read_rnd_buffer_size = 8M
myisam_sort_buffer_size = 64M
read_buffer_size=128K
open_files_limit = 1000
table_definition_cache = 1024
table_open_cache = 6000
max_heap_table_size=512M
tmp_table_size=4096M
max_connections=1000
thread_concurrency = 24
Berikut ini adalah pengaturan perangkat keras:
- Dell R710
- RAID10
- RAM 48G
Mengingat perangkat keras ini, saya tidak akan mengharapkan masalah menjadi hambatan perangkat keras.
Jawaban:
PENGAMATAN # 1
Hal pertama yang menarik perhatian saya adalah struktur meja
Harap perhatikan bahwa
categoriesId
indeks dan KUNCI UTAMA dimulai dengan kolom yang sama. Ini adalah indeks yang berlebihan. Karena tabel ini adalah InnoDB,categoriesId
indeksnya berlebihan karena alasan lain: Semua indeks sekunder berisi kunci ke gen_clust_index (alias Clustered Index; Lihat apa yang digunakan gen_clust_index di mysql? )Jika Anda menghapus
categoriesId
indeks denganini akan meningkatkan INSERT secara dramatis karena tidak harus melakukan pemeliharaan indeks Sekunder dan Klaster tambahan.
PENGAMATAN # 2
Jika Anda melakukan operasi penyisipan massal, Anda memerlukan buffer penyisipan massal yang besar .
Silakan lihat posting saya yang lalu tentang ini:
PENGAMATAN # 3
Ukuran file log Anda terlalu kecil !!! Itu harus 25% dari Pool Buffer InnoDB, yang dalam kasus Anda harus 1G. Lihat posting saya tentang cara mengubah ukuran File Log InnoDB .
PENGAMATAN # 4
Tolong, jangan atur innodb_thread_concurrency !!! Saya belajar langsung di Percona Live NYC untuk meninggalkan pengaturan itu sendirian . Ini dinonaktifkan secara default di MySQL 5.5, Plugin MySQL 5.1 InnoDB, dan Percona Server 5.1+.
PENGAMATAN # 5
Anda perlu menggunakan innodb_file_per_table. Jika ini dinonaktifkan, saya membuat pemeliharaan file pada ibdata1 mimpi buruk. Baca posting saya tentang cara membersihkan InnoDB untuk menerapkan ini .
PENGAMATAN # 6
Jika Anda menggunakan MySQL 5.5 atau Percona Server, Anda harus mengatur opsi tertentu untuk membuat InnoDB menggunakan mutiple CPUs / multiple core. Silakan lihat posting saya di pengaturan itu .
PENGAMATAN # 7
Kamu punya
innodb_log_buffer_size=4M
. Standarnya adalah 8M. Itu akan menyebabkan pembilasan dua kali lebih banyak ke redo log. Itu juga akan menangkalinnodb_flush_log_at_trx_commit=2
pengaturan Anda . Harap setel ke 32M. Juga, silakan lihat Dokumentasi MySQL di innodb_log_buffer_size .Sehubungan dengan pengamatan ini, silakan tambahkan atau ganti pengaturan berikut:
sumber
query_cache_size
sangat besar juga. Setiap sisipan akan membutuhkan cache hingga 6GB untuk bisa dihapus.Anda harus memeriksa
innodb_log_file_size
, pengaturan default adalah 5M yang cukup rendah untuk pengaturan menulis intensif. Pertimbangkan untuk mengaturnya ke 100 juta. Anda harus menghapusib_logfile*
file lama untuk memulai DB dengan pengaturan baru. Tolong jangan menghapus file log saat server DB sedang berjalan, Anda harus menghentikannya terlebih dahulu. Mungkin Anda harus membuat cadangan file log lama terlebih dahulu, bukan hanya menghapusnya.sumber