INSERT ... SELECT ...
kueri memperoleh kunci BERSAMA
pada baris yang dibaca dari tabel sumber di SELECT. Tetapi dengan memproses potongan baris yang lebih kecil, kunci tidak bertahan terlalu lama.
Kueri dengan LIMIT ... OFFSET
akan menjadi lebih lambat dan lebih lambat saat Anda maju melalui tabel sumber. Pada 10.000 baris per potongan, Anda perlu menjalankan kueri itu 10.000 kali, masing-masing harus memulai dari awal dan memindai tabel untuk mencapai OFFSET baru.
Apa pun yang Anda lakukan, menyalin 100 juta baris akan memakan waktu cukup lama. Ini melakukan banyak pekerjaan.
Saya akan menggunakan pt-archiver , alat gratis yang dirancang untuk tujuan ini. Ini memproses baris dalam "potongan" (atau himpunan bagian). Ini akan menyesuaikan ukuran potongan secara dinamis sehingga setiap potongan membutuhkan waktu 0,5 detik.
Perbedaan terbesar antara metode Anda dan pt-archiver adalah pt-archiver tidak menggunakan LIMIT ... OFFSET
, ia berjalan di sepanjang indeks kunci utama, memilih potongan baris berdasarkan nilai, bukan berdasarkan posisi. Jadi setiap potongan dibaca lebih efisien.
Kembali komentar Anda:
Saya berharap membuat ukuran batch lebih kecil — dan meningkatkan jumlah iterasi — akan membuat masalah kinerja lebih buruk , tidak lebih baik.
Alasannya adalah ketika Anda menggunakan LIMIT
dengan OFFSET
, setiap kueri harus memulai kembali dari awal tabel, dan menghitung baris hingga OFFSET
nilai. Ini menjadi lebih lama dan lebih lama saat Anda mengulangi tabel.
Menjalankan 20.000 kueri mahal menggunakan OFFSET
akan memakan waktu lebih lama daripada menjalankan 10.000 kueri serupa. Bagian yang paling mahal tidak akan membaca 5.000 atau 10.000 baris, atau memasukkannya ke tabel tujuan. Bagian yang mahal akan melewati ~50.000.000 baris, berulang-ulang.
Sebagai gantinya, Anda harus mengulangi tabel dengan nilai bukan dengan offset.
INSERT IGNORE INTO Table2(id, field2, field3)
SELECT f1, f2, f3
FROM Table1
WHERE id BETWEEN rowOffset AND rowOffset+limitSize;
Sebelum loop, kueri MIN(id) dan MAX(id), dan mulai rowOffset
pada nilai minimum, dan ulangi hingga nilai maksimum.
Ini adalah cara kerja pt-archiver.