从一个 MySQL 表复制到同一数据库的另一个 MySQL 表

Dev*_*xit 15 mysql insert bulk-insert

我在 MySQL 表中有大约 4000 万行,我想将此表复制到同一数据库中的另一个表。这样做的最有效方法是什么?需要多少时间(大约)?

Rol*_*DBA 24

假设您拥有mydb.mytb并且想要创建mydb.mytbcopy

我有五(5)种方法来做这个副本

方法#1

mysql客户端,运行以下命令

USE mydb
CREATE TABLE mytbcopy LIKE mytb;
INSERT INTO mytbcopy SELECT * FROM mytb;
Run Code Online (Sandbox Code Playgroud)

方法#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"
Run Code Online (Sandbox Code Playgroud)

方法#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"
Run Code Online (Sandbox Code Playgroud)

方法#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
Run Code Online (Sandbox Code Playgroud)

方法#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}
Run Code Online (Sandbox Code Playgroud)

分析

  • 方法#1就步骤而言是最简单的,但需要将 4000 万行推送到一个事务中。这将是对 InnoDB 存储引擎的最大负担。
  • 对于其他方法,mysqldump 将在数千行的卡盘中发送 4000 万行
    • APPROACH #2APPROACH #3会将表 mysqldump 到测试数据库中。在测试数据库中创建表后,随后将其重命名并移动到原始数据库中
    • APPROACH #4APPROACH #5使用sed针对来自 mysqldump 的流重命名表,因为它回显了 INSERT 命令
    • 方法 #2方法 #4使用管道而不是输出文件
    • APPROACH #3APPROACH #5使用输出文件进行后续重新加载

如果要复制mydb.mytb到一个已经存在的表mydb.mytbcopy,并且两个表具有相同的结构:

方法#6

INSERT INTO mytbcopy SELECT * FROM mytb;
Run Code Online (Sandbox Code Playgroud)

#APPROACH 1一样,#APPROACH 6将有一个 4000 万行的事务

方法#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
Run Code Online (Sandbox Code Playgroud)

这种方法不会删除表。它只是生成插入

结语

由于我不知道 DB Server 的组成、表结构、索引布局和诸如此类的东西,我无法给您估计时间。

试一试 !!!