在mysql中复制表的最快方法?


82

我想在MySQL中复制表。最快的方法是什么?像这样?

CREATE TABLE copy LIKE original;
INSERT INTO copy SELECT * FROM original;

要么

CREATE TABLE copy SELECT * FROM original;
ALTER TABLE copy ADD PRIMARY KEY (id);

还是有另一种方法?

编辑:我担心正在重新创建索引,mysql如何继续执行这些语句?

PS。不能使用mysqldump之类的命令行工具,必须是即时的。

Answers:


50

这将立即复制表的结构,但不会复制数据:

CREATE TABLE copy LIKE original;

这将创建original表具有的所有索引。

它在mysql中以这种方式工作5.1.39


3
但是,它不会复制触发器。
ursitesion

3
注意,这也不会复制外键约束。
Omer Sabic

47

使用MyISAM表同时保留index和其他存储引擎的最快方法是:

CREATE TABLE copy LIKE original;
ALTER TABLE copy DISABLE KEYS;
INSERT INTO copy SELECT * FROM original;
ALTER TABLE copy ENABLE KEYS;

您要为数据库加载禁用密钥,然后最后重新创建密钥。

同样,对于InnoDB

SET unique_checks=0; SET foreign_key_checks=0; 
..insert sql code here..
SET unique_checks=1; SET foreign_key_checks=1;

(如评论中指出。)


1
奇怪。用键插入需要36分钟,而此方法需要10 + 26分钟(插入+更改)。6个索引,28M条记录,Win 7 x64、8GB RAM。
Per Lindberg 2015年

ENABLE KEYS导致“修复表”。检查您的过程列表以这种方式发生。有两种:1.带有键缓存的修复表2.通过排序修复表第二种是斋戒方式,仅当myisam_max_sort_file_size足够大时才使用。 dev.mysql.com/doc/refman/5.7/en/repair-table-speed.html
洛波

ALTER TABLE table DISABLE/ENABLE KEYS在InnoDB中不起作用,并给出以下警告Table storage engine for 'table' doesn't have this option
Amil Waduwawara '16

1
for innodbSET unique_checks=0; SET foreign_key_checks=0;在这里使用插入sql代码SET unique_checks=1; SET foreign_key_checks=1;
tuku

13

手册

“ CREATE TABLE ... SELECT不会自动为您创建任何索引。这样做是为了使该语句尽可能灵活。如果要在创建的表中包含索引,则应在SELECT语句之前指定这些索引:”

CREATE TABLE bar (UNIQUE (n)) SELECT n FROM foo;

您可以与两个指定索引和数据类型(以避免数据类型转换)CREATE TABLE LIKECREATE TABLE SELECT。哪一个速度更快取决于您的设置。


9

要使用索引和触发器进行复制,请执行以下两个查询:

CREATE TABLE newtable LIKE oldtable; 
INSERT newtable SELECT * FROM oldtable;

要仅复制结构和数据,请使用以下代码:

CREATE TABLE tbl_new AS SELECT * FROM tbl_old;

不应该INSERT INTO代替INSERT吗?
佐丹奴

6

是否create table mynewtable (select * from myoldtable)在MySQL的工作?如果是这样,您也可以尝试。


5

将结构和所有条目从一个表复制到另一表(通过创建新表)的最佳方法是此查询...

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


3

尝试SELECT INTO使用,并使用一个变量作为中间标记。

首先,必须创建接收表,使其结构与源表相同。

最好的是,它是内部的,因此速度很快。但是,您将丢失索引。


MySQL不支持Select into
Draco Ater 2010年

@Draco Ater-是的,确实如此。它仅使用变量。
amphetamachine,2010年

2
你能举个例子吗?因为我认为,变量将仅保存由select读取的最后一个值,而不是表中的所有值。只要您不使用游标并且不想复制多于一行的表,该解决方案就根本不起作用。
fancyPants 2013年

2

如果使用的是MyISAM,还可以复制和重命名单个文件。后端的.MYD,.MYI,.FRM文件



0
CREATE TABLE copy SELECT * FROM original;

这是一种快速的方法,但可能不是最快的索引原因。


请编辑您的答案并正确设置其格式以使其可读。
Neeku 2014年

1
该语句既不复制索引也不与该表关联的触发器。
ursitesion
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.