2012-06-25 3 views
15

Есть ли более-ЭФФЕКТИВНЫЙ, менее трудоемкий способ копирования всех записей из одной таблицы в другую, что делает это:MySQL эффективно скопировать все записи из одной таблицы в другую

INSERT INTO product_backup SELECT * FROM product 

Обычно product таблицы будет держать около 50 000 записей. Обе таблицы идентичны по структуре и содержат 31 столбцов. Я хотел бы указать, что это не мой проект базы данных, я унаследовал устаревшую систему.

+5

Я думает, что это лучший способ. Таким образом, вы также сохраняете индексы. –

+1

Speedwise это примерно так же хорошо, как и получается. Конечно, вы можете отложить создание индекса в таблице резервного копирования до тех пор, пока все данные не будут скопированы, что значительно увеличит скорость ввода. – fvu

+0

Это интересно, спасибо. Я был любопытен вокруг копирования данных и задавался вопросом, было ли это утечкой в ​​базе данных («SELECT *» отбросил меня, или это займет много времени для обработки из-за способа построения запроса). Если это приемлемый способ копирования данных, то это прекрасно. – crmpicco

ответ

9

Я думаю, что это лучший способ скопировать записи из одной таблицы в другую. Таким образом, вы также сохраняете существующие индексы целевой таблицы.

1

Я не думаю, что это будет достойно для таблицы 50k, но: Если у вас есть дамп базы данных, вы можете перезагрузить таблицу из нее. Как вы хотите загрузить таблицу в другой можно изменить имя таблицы в отвал с SED команды: Вот вам несколько советов: http://blog.tsheets.com/2008/tips-tricks/mysql-restoring-a-single-table-from-a-huge-mysqldump-file.html

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

И лучшей альтернативой могло бы стать создание другого экземпляра MySQL и запуск его в конфигурации ведущий-ведомый или в режиме ведомого сервера/загрузки.

4
mysqldump -R --add-drop-table db_name table_name > filepath/file_name.sql 

Это займет дамп указанных таблиц с возможностью удаления, чтобы удалить существующую таблицу при ее импорте. затем делать,

mysql db_name < filepath/file_name.sql 
+0

Я должен был добавить, что я делаю это в PHP-коде. Это будет сделано до того, как серия INSERT и UPDATE будут выполняться в таблице 'product', поэтому я бы хотел сделать это в PHP-коде, а не в функциях администрирования MySQL. – crmpicco

12

Есть только одна вещь, которую вам не хватает. Особенно, если вы используете InnoDB, что вы хотите, чтобы явно добавить ORDER BY пункта в вашем ЗЕЬЕСТЕ, чтобы убедиться, что вы вставка строк в первичном ключе (кластерный индекс) порядок:

INSERT INTO product_backup SELECT * FROM product ORDER BY product_id 

Рассмотрите возможность удаления вторичных индексов на резервную таблицу, если они не нужны. Это также сэкономит некоторую нагрузку на сервере.

Наконец, если вы используете InnoDB, уменьшить количество блокировок строк, которые необходимы и просто явно заблокировать обе таблицы:

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

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

+0

Я использую движок MyISAM. В предыдущей статье я упомянул, что унаследовал устаревшую систему, поэтому на данный момент это MyISAM. – crmpicco

+0

не может заказать создание дерева индексов, которое не сбалансировано? В каком случае случайный порядок может быть лучше для первичного ключа? –

+0

@ DannyStaple, дерево является плоским при вставке в индекс в отсортированном порядке с MyISAM. Это повышает производительность (не перестраивая индекс), а также экономит место. Из [документации MySQL] (http://dev.mysql.com/doc/refman/5.0/en/myisam-storage-engine.html): «Когда строки вставляются в отсортированный порядок (как при использовании столбца AUTO_INCREMENT), дерево индексов разделяется так, что высокий узел содержит только один ключ, что улучшает использование пространства в дереве индексов. " –

1

DROP назначения таблице:

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

Что делать, если в таблице назначения есть данные, которые OP хочет сохранить и добавить? – Martin

+0

Зачем бросать и создавать таблицу вместо DELETE FROM destination_table; INSERT INTO destination_table SELECT * FROM product? Какой из них эффективнее? –

Смежные вопросы