Salin dari satu tabel MySQL ke tabel MySQL lain dari database yang sama

15

Saya memiliki sekitar 40 juta baris dalam tabel MySQL dan saya ingin menyalin tabel ini ke tabel lain dalam database yang sama. Apa cara paling efisien untuk melakukan ini? Berapa lama waktu yang dibutuhkan (kurang-lebih)?

Devashish Dixit
sumber
Apa Engine meja Anda?
Abdul Manaf
InnoDB Engine ..
Devashish Dixit

Jawaban:

23

Misalkan Anda memiliki mydb.mytbdan ingin membuatmydb.mytbcopy

Saya memiliki lima (5) pendekatan untuk melakukan salinan ini

PENDEKATAN # 1

Di mysqlklien, jalankan yang berikut ini

USE mydb
CREATE TABLE mytbcopy LIKE mytb;
INSERT INTO mytbcopy SELECT * FROM mytb;

PENDEKATAN # 2

MYSQL_USER=root
MYSQL_PASS=rootpassword
MYSQL_CONN="-u${MYSQL_USER} -p${MYSQL_PASS}"
mysql ${MYSQL_CONN} -ANe"CREATE DATABASE IF NOT EXISTS test"
mysqldump ${MYSQL_CONN} mydb mytb | mysql ${MYSQL_CONN} -Dtest
mysql ${MYSQL_CONN} -ANe"ALTER TABLE test.mytb RENAME mydb.mytbcopy"

PENDEKATAN # 3

DUMPFILE=/some/path/tabledata.sql
MYSQL_USER=root
MYSQL_PASS=rootpassword
MYSQL_CONN="-u${MYSQL_USER} -p${MYSQL_PASS}"
mysql ${MYSQL_CONN} -ANe"CREATE DATABASE IF NOT EXISTS test"
mysqldump ${MYSQL_CONN} mydb mytb > ${DUMPFILE}
mysql ${MYSQL_CONN} -Dtest < ${DUMPFILE}
rm -f ${DUMPFILE}
mysql ${MYSQL_CONN} -ANe"ALTER TABLE test.mytb RENAME mydb.mytbcopy"

PENDEKATAN # 4

MYSQL_USER=root
MYSQL_PASS=rootpassword
MYSQL_CONN="-u${MYSQL_USER} -p${MYSQL_PASS}"
mysqldump ${MYSQL_CONN} mydb mytb | sed 's/mytb/mytbcopy' | mysql ${MYSQL_CONN} -Dmydb

PENDEKATAN # 5

DUMPFILE=/some/path/tabledata.sql
MYSQL_USER=root
MYSQL_PASS=rootpassword
MYSQL_CONN="-u${MYSQL_USER} -p${MYSQL_PASS}"
mysqldump ${MYSQL_CONN} mydb mytb | sed 's/mytb/mytbcopy' > ${DUMPFILE}
mysql ${MYSQL_CONN} -Dmydb < ${DUMPFILE}
rm -f ${DUMPFILE}

ANALISIS

  • PENDEKATAN # 1 adalah yang termudah dalam hal langkah-langkah, tetapi mengharuskan mendorong 40 juta baris ke dalam satu transaksi. Ini akan menjadi yang paling memberatkan di InnoDB Storage Engine.
  • Untuk pendekatan lain, mysqldump akan mengirimkan 40 juta baris dalam chucks dari ribuan baris
    • PENDEKATAN # 2 dan PENDEKATAN # 3 akan mysqldump tabel ke dalam database pengujian. Setelah membuat tabel dalam database pengujian, selanjutnya diubah namanya dan dipindahkan ke database asli
    • PENDEKATAN # 4 dan PENDEKATAN # 5 mengubah nama tabel menggunakan sed terhadap aliran yang berasal dari mysqldump saat itu menggemakan perintah INSERT
    • PENDEKATAN # 2 dan PENDEKATAN # 4 menggunakan pipa bukan file output
    • PENDEKATAN # 3 dan PENDEKATAN # 5 menggunakan file outpuit untuk memuat ulang berikutnya

Jika Anda ingin menyalin mydb.mytbke tabel yang sudah ada mydb.mytbcopy, dan kedua tabel memiliki struktur yang identik:

PENDEKATAN # 6

INSERT INTO mytbcopy SELECT * FROM mytb;

Seperti #APPROACH 1 , #APPROACH 6 akan memiliki satu transaksi 40 juta baris

PENDEKATAN # 7

MYSQL_USER=root
MYSQL_PASS=rootpassword
MYSQL_CONN="-u${MYSQL_USER} -p${MYSQL_PASS}"
mysqldump ${MYSQL_CONN} -t mydb mytb | sed 's/mytb/mytbcopy' | mysql ${MYSQL_CONN} -Dmydb

Pendekatan ini tidak menjatuhkan tabel. Ini hanya menghasilkan INSERT

EPILOG

Saya tidak bisa memberi Anda perkiraan waktu karena saya tidak tahu susunan DB Server, struktur tabel, tata letak indeks, dan hal-hal seperti ini.

COBALAH !!!

RolandoMySQLDBA
sumber
0

Tabel InnoDB, tidak seperti MyISAM *, tidak dapat "disalin begitu saja", sebagai bagian dari kamus datanya (dan berpotensi struktur lain yang bergantung pada tabel, seperti buffer gabungan) terletak di memori (jika server sedang berjalan) dan di tablespace umum / utama, alias file besar yang disebut ibdata1 .

Jika Anda menggunakan Percona Server> = 5.1 atau MySQL> = 5.6, ada dukungan untuk tablespace yang dapat diangkut, yang memungkinkan Anda untuk mengekspor dan mengimpor tabel secara langsung dari sistem file. Ini dia metode untuk MySQL dan untuk Percona . Dalam kedua kasus, Anda harus membuat tabel denganinnodb_file_per_table opsi dan melibatkan penggunaan DISCARD TABLESPACE/IMPORT TABLESPACEdan / atau Percona Xtrabakup (jika Anda ingin ekspor dilakukan secara online). Harap dicatat bahwa Percona Server atau Xtrabakup tidak tersedia untuk Windows.

Metode ini akan, secara umum, secepat menyalin file menggunakan perintah filesystem (cp, rsync).

Walaupun mungkin ada beberapa kasus bahwa ini bisa bekerja di MySQL <5.6 (dengan cara hacky) untuk mengembalikan, itu tidak akan berfungsi untuk salinan tabel. Dalam kasus tersebut, salah satu cara untuk melakukannya adalah dengan menggunakan SQL :

CREATE TABLE new_table LIKE old_table;
INSERT INTO new_table SELECT * FROM old_table;

Ini akan secepat yang InnoDB dapat jalankan Handler_read_rnd_nextdanHandler_write , sekali per baris. Jika Anda menggunakan metode ini, pastikan bahwa Anda menonaktifkan, setidaknya untuk sementara, opsi daya tahan dan Anda memiliki kumpulan buffer besar dan log transaksi. Dalam keadaan seperti itu, ini dapat mengurangi waktu impor, tetapi pasti tidak akan masuk ke memori sepenuhnya, jadi harap banyak waktu. Selain itu, Anda mencoba mengimpor 40 juta baris dalam satu transaksi, yang dapat menyebabkan masalah.

Rekomendasi saya yang sebenarnya, dalam kasus kedua ini, adalah menggunakan sesuatu seperti pt-archiver , karena akan melakukan operasi yang mirip dengan yang saya sebutkan, tetapi akan dilakukan dalam "bongkahan", menghindari overhead transaksional (mungkin overhead tidak lebih cepat, tetapi dalam kasus kegagalan, itu tidak akan mencoba untuk mengembalikan seluruh tabel, mengambil selamanya). Untuk ukuran data yang Anda sebutkan, ini mungkin cara terbaik untuk melakukannya.

Opsi terakhir adalah mengekspor dan mengimpor menggunakan format CSV (atau TSV) , dengan kombinasi SELECT INTO OUTFILE / mysqldump dan LOAD DATA / mysqlimport. Ini adalah pilihan yang sangat umum jika Anda membutuhkan konkurensi dalam versi lama mysql, karena menggunakan sql membuat kunci lebih besar (tidak benar lagi jika dilakukan dengan benar). Karena mysqldump / import hanya berfungsi secara serial, saya akan merekomendasikan Anda untuk meneliti opsi untuk memparalelkannya, sangat berguna untuk tabel besar.

Bagaimanapun, cobalah untuk menghindari beberapa kalimat SQL, karena itu akan menjadi hambatan Anda yang paling penting jika Anda menjalankan banyak pertanyaan yang berbeda (yang harus dieksekusi, diuraikan dan dioptimalkan secara individual).


* Struktur MyISAM tidak dapat disalin dengan cara yang panas, tetapi sangat mudah untuk menyinkronkannya sementara ke disk dengan FTWRL.

jynus
sumber
0

untuk Memindahkan data dari satu tabel ke tabel lainnya dalam skema

create table your_table_name select * from old_schema_table;

Shahzad Hussain
sumber