如何循环并复制大型MySQL表的每一行?

时间:2016-02-07 22:15:28

标签: mysql stored-procedures mysqldump

方案:

我有一个拥有1100万行的MySQL MyISAM表(table1),所有这些我想要复制到更好的表(table2,它具有InnoDB引擎以及正确的索引)。由于将索引添加到MyISAM表只需要太长时间,我想循环遍历整个表并将每一行复制到新表。

有没有办法在MySQL中执行此操作?

条件:

  • 这个动作没有时间限制(可以循环播放"慢慢地")。
  • 表格具有相同的列。
  • table1在线,需要保持在线状态(一直在阅读;我暂时暂停了写作)。

的问题:

  • MySQL服务器是共享主机(无文件系统访问)。
  • Mysqldump超时。
  • 添加索引超时。
  • 只需插入前一个表格的选择即可。

点子:

也许有人可以把它作为MySQL声明循环,一次做10 000个或类似的东西?

这适用于一(1)条记录:

INSERT INTO products_indexed
SELECT * FROM products
WHERE products.p_product_id=(
    SELECT products.p_product_id AS id FROM products
    LEFT OUTER JOIN products_indexed ON (
        products.p_product_id = products_indexed.p_product_id
    )
    WHERE products_indexed.p_product_id IS NULL
    LIMIT 1
)

然后可以使用存储过程循环:

BEGIN
DECLARE x  INT; 
SET x = 1;

WHILE x  <= 1000000 DO
SET  x = x + 1; 

INSERT INTO products_indexed
SELECT * FROM products
WHERE products.p_product_id=(
    SELECT products.p_product_id AS id FROM products
    LEFT OUTER JOIN products_indexed ON (
        products.p_product_id = products_indexed.p_product_id
    )
    WHERE products_indexed.p_product_id IS NULL
    LIMIT 1
);

END WHILE;

END

这可能不是最好的循环方式,但这是一次尝试。似乎工作,但我将如何优化它? (也许做查询得到几千行,然后进行INSERT?

2 个答案:

答案 0 :(得分:0)

http://dev.mysql.com/doc/refman/5.7/en/converting-tables-to-innodb.html

To convert a non-InnoDB table to use InnoDB use ALTER TABLE:

ALTER TABLE table_name ENGINE=InnoDB;

答案 1 :(得分:0)

看看pt-online-schema-change。它有一个确切的例子:

pt-online-schema-change --alter "ENGINE=InnoDB" D=sakila,t=actor

顾名思义,它将通过创建重复表并执行原子重命名作为最后一步来在线执行更改而不进行锁定。

很难说你是否会遇到相同的锁定问题,但希望不会!