Копировать из одной таблицы MySQL в другую таблицу MySQL той же базы данных


15

У меня около 40 миллионов строк в таблице MySQL, и я хочу скопировать эту таблицу в другую таблицу в той же базе данных. Каков наиболее эффективный способ сделать это? Сколько времени это займет (прибл.)?


Какой двигатель у твоего стола?
Абдул Манаф

Двигатель InnoDB ..
Devashish Dixit

Ответы:


23

Предположим, у вас есть, mydb.mytbи вы хотите создатьmydb.mytbcopy

У меня есть пять (5) подходов к созданию этой копии

ПОДХОД № 1

В mysqlклиенте запустите следующее

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

ПОДХОД № 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"

ПОДХОД № 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"

ПОДХОД № 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

ПОДХОД № 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}

АНАЛИЗ

  • ПОДХОД № 1 является самым простым с точки зрения шагов, но требует помещения 40 миллионов строк в одну транзакцию. Это будет самым обременительным для InnoDB Storage Engine.
  • Для других подходов mysqldump отправит 40 миллионов строк в кусках тысяч строк
    • APPROACH # 2 и APPROACH # 3 будут mysqldump таблицу в тестовую базу данных. После создания таблицы в тестовой базе данных она впоследствии переименовывается и перемещается в исходную базу данных.
    • APPROACH # 4 и APPROACH # 5 переименовывают таблицу, используя sed для потока, идущего из mysqldump, поскольку он повторяет команды INSERT
    • APPROACH # 2 и APPROACH # 4 используют каналы вместо выходного файла
    • ПОДХОД № 3 и ПОДХОД № 5 используют выходной файл для последующей перезагрузки

Если вы хотите скопировать mydb.mytbв уже существующую таблицу mydb.mytbcopy, и две таблицы имеют идентичные структуры:

ПОДХОД № 6

INSERT INTO mytbcopy SELECT * FROM mytb;

Подобно #APPROACH 1 , #APPROACH 6 будет иметь одну транзакцию из 40 миллионов строк

ПОДХОД № 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

Этот подход не опускает стол. Он просто генерирует ВСТАВКИ

Эпилог

Я не могу дать вам оценку времени, так как я не знаю состав сервера БД, структуру таблицы, структуру индекса и тому подобное.

Дайте ему попробовать!


0

Таблицы InnoDB, в отличие от MyISAM *, нельзя «просто скопировать», поскольку часть их словаря данных (и, возможно, других структур, от которых зависит таблица, например, буфер слияния) расположены в памяти (если сервер работает) и в общее / основное табличное пространство, называемое тем большим файлом ibdata1.

Если вы используете Percona Server> = 5.1 или MySQL> = 5.6, есть поддержка переносимых табличных пространств, которая позволяет вам экспортировать и импортировать таблицы непосредственно из файловой системы. Здесь это метод для MySQL и для Percona . В обоих случаях требуется, чтобы вы создали таблицу с этой innodb_file_per_tableопцией и DISCARD TABLESPACE/IMPORT TABLESPACEвключали использование и / или Percona Xtrabakup (если вы хотите, чтобы экспорт осуществлялся онлайн). Обратите внимание, что Percona Server или Xtrabakup недоступны для Windows.

В общем случае этот метод будет таким же быстрым, как копирование файла с помощью команд файловой системы (cp, rsync).

Хотя могут быть некоторые случаи, когда это может работать в MySQL <5.6 (хакерским способом) для восстановления, это не будет работать для копии таблицы. В этих случаях одним из способов сделать это является использование SQL :

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

Это будет так же быстро, как InnoDB, Handler_read_rnd_nextи Handler_writeодин раз за строку. Если вы используете этот метод, убедитесь, что вы отключили, хотя бы временно, параметры долговечности, и у вас есть большой пул буферов и журнал транзакций. При таких обстоятельствах это может сократить время импорта, но определенно не уместится в память полностью, поэтому ожидайте много времени. Кроме того, вы пытаетесь импортировать 40M строк в одной транзакции, что может привести к проблемам.

Моя фактическая рекомендация в этом втором случае - использовать что-то вроде pt-archiver , поскольку он будет выполнять операцию, аналогичную той, которую я только что упомянул, но это будет выполняться «кусками», избегая накладных расходов на транзакции (это может не будет быстрее, но в случае сбоя он не будет пытаться откатить всю таблицу, занимая вечность). Для размеров данных, которые вы упоминаете, это, вероятно, лучший путь.

Последний вариант - экспорт и импорт в формате CSV (или TSV) с комбинацией SELECT INTO OUTFILE / mysqldump и LOAD DATA / mysqlimport. Это был очень распространенный вариант, если вам требовался параллелизм в некоторых старых версиях mysql, так как использование sql создавало большие блокировки (больше не верно, если все сделано правильно). Поскольку mysqldump / import работает только в последовательном порядке, я бы порекомендовал вам изучить варианты его распараллеливания, что очень полезно для больших таблиц.

В любом случае, старайтесь избегать множественных предложений SQL, так как это будет вашим самым важным узким местом, если вы выполняете много разных запросов (которые должны выполняться, анализироваться и оптимизироваться индивидуально).


* Структуры MyISAM не могут быть скопированы горячим способом, но их очень легко временно синхронизировать с диском FTWRL.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.