Pertanyaan ini diposting ulang dari Stack Overflow berdasarkan saran di komentar, permintaan maaf untuk duplikasi.
Pertanyaan
Pertanyaan 1: saat ukuran tabel basis data semakin besar, bagaimana saya bisa menyetel MySQL untuk meningkatkan kecepatan panggilan LOAD DATA INFILE?
Pertanyaan 2: apakah akan menggunakan sekelompok komputer untuk memuat file csv yang berbeda, meningkatkan kinerja atau membunuhnya? (ini adalah tugas menandai bangku saya untuk besok menggunakan data muatan dan sisipan massal)
Tujuan
Kami mencoba kombinasi berbeda dari pendeteksi fitur dan parameter pengelompokan untuk pencarian gambar, sebagai akibatnya kami harus dapat membangun dan database besar secara tepat waktu.
Info Mesin
Mesin memiliki 256 gig ram dan ada 2 mesin lain yang tersedia dengan jumlah ram yang sama jika ada cara untuk meningkatkan waktu pembuatan dengan mendistribusikan database?
Skema Tabel
skema tabel terlihat seperti
+---------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+------------------+------+-----+---------+----------------+
| match_index | int(10) unsigned | NO | PRI | NULL | |
| cluster_index | int(10) unsigned | NO | PRI | NULL | |
| id | int(11) | NO | PRI | NULL | auto_increment |
| tfidf | float | NO | | 0 | |
+---------------+------------------+------+-----+---------+----------------+
dibuat dengan
CREATE TABLE test
(
match_index INT UNSIGNED NOT NULL,
cluster_index INT UNSIGNED NOT NULL,
id INT NOT NULL AUTO_INCREMENT,
tfidf FLOAT NOT NULL DEFAULT 0,
UNIQUE KEY (id),
PRIMARY KEY(cluster_index,match_index,id)
)engine=innodb;
Benchmarking sejauh ini
Langkah pertama adalah membandingkan sisipan massal vs memuat dari file biner ke tabel kosong.
It took: 0:09:12.394571 to do 4,000 inserts with 5,000 rows per insert
It took: 0:03:11.368320 seconds to load 20,000,000 rows from a csv file
Mengingat perbedaan dalam kinerja saya telah pergi dengan memuat data dari file csv biner, pertama saya memuat file biner yang berisi 100K, 1M, 20M, 200M baris menggunakan panggilan di bawah ini.
LOAD DATA INFILE '/mnt/tests/data.csv' INTO TABLE test;
Saya membunuh file biner baris 200M (~ file csv 3GB) dimuat setelah 2 jam.
Jadi saya menjalankan skrip untuk membuat tabel, dan memasukkan nomor baris yang berbeda dari file biner kemudian menjatuhkan tabel, lihat grafik di bawah ini.
Butuh sekitar 7 detik untuk menyisipkan baris 1M dari file biner. Selanjutnya saya memutuskan untuk benchmark memasukkan 1M baris sekaligus untuk melihat apakah akan ada hambatan pada ukuran database tertentu. Setelah Database mencapai sekitar 59M baris, waktu memasukkan rata-rata turun menjadi sekitar 5.000 / detik
Mengatur key_buffer_size global = 4294967296 meningkatkan kecepatan sedikit untuk memasukkan file biner yang lebih kecil. Grafik di bawah ini menunjukkan kecepatan untuk jumlah baris yang berbeda
Namun untuk memasukkan baris 1M itu tidak meningkatkan kinerja.
baris: 1.000.000 waktu: 0: 04: 13.761428 sisipan / detik: 3.940
vs untuk database kosong
baris: 1.000.000 waktu: 0: 00: 6.339295 sisipan / detik: 315.492
Memperbarui
Melakukan memuat data menggunakan urutan berikut vs hanya menggunakan perintah memuat data
SET autocommit=0;
SET foreign_key_checks=0;
SET unique_checks=0;
LOAD DATA INFILE '/mnt/imagesearch/tests/eggs.csv' INTO TABLE test_ClusterMatches;
SET foreign_key_checks=1;
SET unique_checks=1;
COMMIT;
Jadi ini terlihat cukup menjanjikan dalam hal ukuran basis data yang sedang dibuat tetapi pengaturan lain tampaknya tidak mempengaruhi kinerja panggilan infil data beban.
Saya kemudian mencoba memuat beberapa file dari mesin yang berbeda tetapi perintah memuat data infile mengunci tabel, karena ukuran file yang besar menyebabkan mesin lain kehabisan waktu dengan
ERROR 1205 (HY000) at line 1: Lock wait timeout exceeded; try restarting transaction
Meningkatkan jumlah baris dalam file biner
rows: 10,000,000 seconds rows: 0:01:36.545094 inserts/sec: 103578.541236
rows: 20,000,000 seconds rows: 0:03:14.230782 inserts/sec: 102970.29026
rows: 30,000,000 seconds rows: 0:05:07.792266 inserts/sec: 97468.3359978
rows: 40,000,000 seconds rows: 0:06:53.465898 inserts/sec: 96743.1659866
rows: 50,000,000 seconds rows: 0:08:48.721011 inserts/sec: 94567.8324859
rows: 60,000,000 seconds rows: 0:10:32.888930 inserts/sec: 94803.3646283
Solusi: Precomputing id di luar MySQL alih-alih menggunakan penambahan otomatis
Membangun meja dengan
CREATE TABLE test (
match_index INT UNSIGNED NOT NULL,
cluster_index INT UNSIGNED NOT NULL,
id INT NOT NULL ,
tfidf FLOAT NOT NULL DEFAULT 0,
PRIMARY KEY(cluster_index,match_index,id)
)engine=innodb;
dengan SQL
LOAD DATA INFILE '/mnt/tests/data.csv' INTO TABLE test FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';"
Membuat skrip untuk melakukan pre-compute indeks tampaknya telah menghapus hit kinerja sebagai database tumbuh dalam ukuran.
Perbarui 2 - menggunakan tabel memori
Secara kasar 3 kali lebih cepat, tanpa memperhitungkan biaya memindahkan tabel di-memori ke meja berbasis disk.
rows: 0 seconds rows: 0:00:26.661321 inserts/sec: 375075.18851
rows: 10000000 time: 0:00:32.765095 inserts/sec: 305202.83857
rows: 20000000 time: 0:00:38.937946 inserts/sec: 256818.888187
rows: 30000000 time: 0:00:35.170084 inserts/sec: 284332.559456
rows: 40000000 time: 0:00:33.371274 inserts/sec: 299658.922222
rows: 50000000 time: 0:00:39.396904 inserts/sec: 253827.051994
rows: 60000000 time: 0:00:37.719409 inserts/sec: 265115.500617
rows: 70000000 time: 0:00:32.993904 inserts/sec: 303086.291334
rows: 80000000 time: 0:00:33.818471 inserts/sec: 295696.396209
rows: 90000000 time: 0:00:33.534934 inserts/sec: 298196.501594
dengan memuat data ke dalam tabel berbasis memori dan kemudian menyalinnya ke meja berbasis disk dalam potongan memiliki overhead 10 menit 59,71 detik untuk menyalin 107.356.741 baris dengan kueri
insert into test Select * from test2;
yang membuatnya sekitar 15 menit untuk memuat 100M baris, yang kira-kira sama dengan langsung memasukkannya ke dalam tabel berbasis disk.
id
menjadi lebih cepat. (Meskipun saya pikir Anda tidak mencari ini)Jawaban:
Pertanyaan bagus - dijelaskan dengan baik.
Anda sudah mendapatkan pengaturan tinggi (ish) untuk buffer kunci - tetapi apakah itu cukup? Saya berasumsi ini adalah instalasi 64-bit (jika tidak maka hal pertama yang perlu Anda lakukan adalah memutakhirkan) dan tidak berjalan di MSNT. Lihat output mysqltuner.pl setelah menjalankan beberapa tes.
Untuk menggunakan cache dengan efek terbaik, Anda mungkin menemukan manfaat dalam batching / pre-sorting data input (versi terbaru dari perintah 'sort' memiliki banyak fungsi untuk menyortir dataset besar). Juga jika Anda menghasilkan nomor ID di luar MySQL, maka mungkin lebih efisien.
Dengan asumsi (sekali lagi) bahwa Anda ingin agar himpunan output berperilaku sebagai tabel tunggal, maka satu-satunya manfaat yang akan Anda dapatkan adalah dengan mendistribusikan pekerjaan menyortir dan membuat id - yang Anda tidak memerlukan database lebih banyak. OTOH menggunakan cluster database, Anda akan mendapatkan masalah dengan pertikaian (yang seharusnya tidak Anda lihat selain sebagai masalah kinerja).
Jika Anda dapat membuang data dan menangani kumpulan data yang dihasilkan secara independen, maka ya, Anda akan mendapatkan manfaat kinerja - tetapi ini tidak meniadakan kebutuhan untuk menyempurnakan setiap node.
Periksa Anda punya setidaknya 4 Gb untuk sort_buffer_size.
Selain itu, faktor pembatas pada kinerja adalah semua tentang disk I / O. Ada banyak cara untuk mengatasinya - tetapi Anda mungkin harus mempertimbangkan set set mirror set data pada SSD untuk kinerja optimal.
sumber
load data...
itu lebih cepat daripada memasukkan, jadi gunakan itu.Jika Anda ingin benar-benar keren, Anda bisa membuat program multi-utas untuk memberi makan satu file ke kumpulan pipa bernama dan mengelola instance sisipan.
Singkatnya, Anda tidak menyetel MySQL untuk ini sebanyak Anda menyesuaikan beban kerja Anda ke MySQL.
sumber
Saya tidak ingat persis syntacx tetapi jika inno db Anda dapat mematikan cek kunci asing.
Anda juga dapat membuat indeks setelah impor, itu bisa menjadi keuntungan kinerja yang sangat.
sumber