【问题标题】:How to copy a very large table into another table in MYSQL?如何将一个非常大的表复制到MYSQL中的另一个表中?
【发布时间】:2017-03-28 21:45:26
【问题描述】:

我有一个有 1.1 亿行的大表。我想将一些字段复制到一个新表中,这里是我尝试做的一个粗略的想法:

    DECLARE l_seenChangesTo DATETIME DEFAULT '1970-01-01 01:01:01';
    DECLARE l_migrationStartTime DATETIME;

    SELECT NOW() into l_migrationStartTime;

    -- See if we've run this migration before and if so, pick up from where we left off...
    IF EXISTS(SELECT seenChangesTo FROM migration_status WHERE client_user = CONCAT('this-migration-script-', user())) THEN
        SELECT seenChangesTo FROM migration_status WHERE client_user = CONCAT('this-migration-script-', user()) INTO l_seenChangesTo;
        SELECT NOW() as LogTime, CONCAT('Picking up from where we left off: ', l_seenChangesTo) as MigrationStatus;
    END IF;

    INSERT IGNORE INTO newTable
        (field1, field2, lastModified)
        SELECT o.column1 AS field1, 
               o.column2 AS field2,
               o.lastModified 
          FROM oldTable o
          WHERE 
                o.lastModified >= l_seenChangesTo AND
                o.lastModified <= l_migrationStartTime;

    INSERT INTO migration_status (client_user,seenChangesTo) 
        VALUES (CONCAT('this-migration-script-', user()), l_migrationStartTime) 
        ON DUPLICATE KEY UPDATE seenChangesTo=l_migrationStartTime;

上下文:

CREATE TABLE IF NOT EXISTS `newTable` (
    `field1`     varchar(255) NOT NULL,
    `field2`      tinyint unsigned NOT NULL,
    `lastModified`        datetime NOT NULL,

    PRIMARY KEY (`field1`, `field2`),
    KEY `ix_field1` (`field1`),
    KEY `ix_lastModified` (`lastModified`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE IF NOT EXISTS `oldTable` (
    `column1`     varchar(255) NOT NULL,
    `column2`      tinyint unsigned NOT NULL,
    `lastModified`        datetime NOT NULL,

    PRIMARY KEY (`column1`, `column2`),
    KEY `ix_column1` (`column1`),
    KEY `ix_lastModified` (`lastModified`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `migration_status` (
        `client_user` char(64) NOT NULL,
        `seenChangesTo` char(128) NOT NULL,

        PRIMARY KEY (`client_user`)
    );

注意:我在 oldTable 中还有几列。 oldTable 和 newTable 都使用 mysql 在同一个数据库模式中。

复制非常表时的一般策略是什么?我是否应该通过一次复制 50,000 行来以迭代方式执行此迁移。

【问题讨论】:

  • 这是从 mysql 到 mssql 还是反过来?
  • 更新后从表迁移到另一个?
  • oldTable 和 newTable 都在使用 mysql 的相同数据库模式中。我正在尝试将同一个数据库复制到一个新表中。更新了问题和标签。
  • 我认为您的方法可以正常工作,另一种方法是恢复同一张表,只需删除不必要的列。

标签: mysql database migration


【解决方案1】:

像这样迭代地进行迁移的插入速度将会非常缓慢。为什么不是SELECT oldTable INTO OUTFILE,然后是LOAD DATA INFILE

【讨论】:

  • 感谢您的回复。在这种情况下,我有一些额外的列,而且并非所有行都需要复制到新表中。我有一些限制。使用列删除和删除从输出文件复制仍然有效吗?
  • @ssk 您可以像任何其他查询一样选择导出到输出文件的字段。您可以从表中选择一些(或全部)列,连接其他表中的列等。唯一的区别是您将结果集定向到文件。然后,您可以使用该文件在新表上进行批量插入。这是进行批量插入时数据仓库操作的标准做法
猜你喜欢
  • 1970-01-01
  • 2011-11-20
  • 1970-01-01
  • 2015-05-17
  • 2012-08-12
  • 2011-07-14
  • 1970-01-01
  • 1970-01-01
  • 2011-06-26
相关资源
最近更新 更多