Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL有效地将所有记录从一个表复制到另一个表_Mysql_Sql_Insert_Mysql5 - Fatal编程技术网

MySQL有效地将所有记录从一个表复制到另一个表

MySQL有效地将所有记录从一个表复制到另一个表,mysql,sql,insert,mysql5,Mysql,Sql,Insert,Mysql5,是否有一种更有效、更省力的方法可以将所有记录从一个表复制到另一个表: INSERT INTO product_backup SELECT * FROM product 通常,产品表将保存大约50000条记录。两个表的结构相同,共有31列。我想指出这不是我的数据库设计,我继承了一个遗留系统。我认为这不值得一个50k表,但是: 如果有数据库转储,可以从中重新加载表。当您想在另一个表中加载一个表时,可以使用sed命令更改转储中的表名: 这里有一些提示: 另一种选择(取决于您的设计)是在原始表插入上

是否有一种更有效、更省力的方法可以将所有记录从一个表复制到另一个表:

INSERT INTO product_backup SELECT * FROM product

通常,
产品
表将保存大约50000条记录。两个表的结构相同,共有31列。我想指出这不是我的数据库设计,我继承了一个遗留系统。

我认为这不值得一个50k表,但是: 如果有数据库转储,可以从中重新加载表。当您想在另一个表中加载一个表时,可以使用sed命令更改转储中的表名: 这里有一些提示:

另一种选择(取决于您的设计)是在原始表插入上使用触发器,以便复制的表也获得数据

更好的选择是创建另一个MySQL实例,并以主从配置或每日转储主/从方式运行它

mysqldump -R --add-drop-table db_name table_name > filepath/file_name.sql
这将使用drop选项转储指定的表,以便在导入现有表时删除该表。那就做,

mysql db_name < filepath/file_name.sql
mysql db_name
您只缺少一件事。特别是,如果使用InnoDB,是否希望在SELECT语句中显式添加ORDER BY子句,以确保按主键(聚集索引)顺序插入行:

如果不需要备份表上的辅助索引,请考虑删除它们。这也将在服务器上节省一些负载

最后,如果您使用的是InnoDB,请减少所需的行锁数量,只需显式锁定两个表:

LOCK TABLES product_backup WRITE;
LOCK TABLES product READ;
INSERT INTO product_backup SELECT * FROM product ORDER BY product_id;
UNLOCK TABLES;

锁定功能可能不会有太大的区别,因为行锁定速度非常快(虽然没有表锁定快),但既然您提出了要求。

DROP
目标表:

DROP TABLE DESTINATION_TABLE;
CREATE TABLE DESTINATION_TABLE AS (SELECT * FROM SOURCE_TABLE);

我认为这是最好的办法。通过这种方式,您也可以保留索引。从速度上来说,这是最好的。当然,您可以将备份表上的索引创建延迟到所有数据都被复制之后,这将显著提高插入速度。这很有趣,谢谢。我对数据的复制很好奇,想知道这是不是消耗了数据库的资源(我被
SELECT*
甩了,还是因为查询的构造方式,需要很长时间才能处理)。如果这是一种可以接受的跨行复制数据的方法,那么也没关系。我认为如果有数百万行,您可能会遇到麻烦。在这种情况下,您可以使用转储/加载解决方案。我在这个表中永远不会有数百万行。我看不出有超过100000个我应该加上我是用PHP代码做这件事的。它将在
产品
表上执行一系列插入和更新之前完成,因此我希望使用PHP代码而不是MySQL管理函数来完成。我使用的是MyISAM引擎。我在之前的一篇文章中提到,我继承了一个遗留系统,所以现在是MyISAM。排序不能创建一个不平衡的索引树吗?在这种情况下,主键的随机顺序可能更好?@DannyStaple,当使用MyISAM按排序顺序插入索引时,树是平坦的。这提高了性能(不必重建索引),并节省了空间。From:“当按排序顺序插入行时(如使用自动增量列时),索引树将被拆分,以便高节点仅包含一个键。这将提高索引树中的空间利用率。”第二个代码块中的第二行应为
锁表产品
product_id
是列。如果目标表中已有OP想要保留和添加的数据,该怎么办?为什么要删除并创建表,而不是从目标表中删除;插入到目标_表中,从产品中选择*?哪一个更有效?Drop将重置主自动增量ID
DROP TABLE DESTINATION_TABLE;
CREATE TABLE DESTINATION_TABLE AS (SELECT * FROM SOURCE_TABLE);