将大量行从数据库 A 的表 1 传输到数据库 B 的表 2 的最快方法是什么

问题描述 投票:0回答:1

我有一个带有表 (

A
) 的 MySql 数据库(数据库
data
),我想将所有这些数据移动到另一个 MySql 数据库(数据库
reading
)中的新表 (
B
) 中。

data
reading
具有不同的结构,因此我不能仅将表 mysqldump 到新数据库中。我当前的方法(有效)需要超过一天的时间。这是查询:

CREATE `uspInsertIgnoreDataInBatches`()
BEGIN
    DECLARE start_index INT DEFAULT 0;
    DECLARE batch_size INT DEFAULT 100000;
    DECLARE total_rows INT;

    -- Get the total count of rows
    SELECT COUNT(*) INTO total_rows
    FROM A.data
    LEFT JOIN A.device_sensor ON data.device_sensor_id = device_sensor.id
    LEFT JOIN A.sensors ON sensors.id = device_sensor.sensor_id;

    -- Loop until all rows are processed
    WHILE start_index < total_rows DO
        BEGIN
            -- Insert data in batches
            INSERT IGNORE INTO B.reading (Id, RecordedAtMT, SensorId, LocationId, SensorValue)
            SELECT data.id, data.datetime, sensors.id as sensor_id, data.location_id, data.value
            FROM A.data
            LEFT JOIN A.device_sensor ON data.device_sensor_id = device_sensor.id
            LEFT JOIN A.sensors ON sensors.id = device_sensor.sensor_id
            ORDER BY A.data.datetime DESC
            LIMIT batch_size OFFSET start_index;
        END;

        -- Move to the next batch
        SET start_index = start_index + batch_size;
    END WHILE;
END

注意:使用

INSERT IGNORE
是因为前一个表中的行将违反新表的唯一约束。

我正在寻找任何能够使此操作尽可能快速高效的解决方案,谢谢。

sql mysql database-migration
1个回答
0
投票

假设你不能使用建议的

SELECT INTO OUTFILE
然后使用
LOAD DATA LOCAL INFILE
,你当然可以让你的SP更有效率。

我们没有有关表的数据量或 DDL 的信息,但时间尺度表明数据集“非常大”。大偏移量的分页可能会非常慢,因此使用 id(假设它是 INT PK)会产生显着的差异。 这是 SP 的修改(且未经测试)版本:

DELIMITER $$ CREATE PROCEDURE `uspInsertIgnoreDataInBatches`() BEGIN DECLARE max_id INT DEFAULT 0; DECLARE batch_size INT DEFAULT 10000; DECLARE max_src_id INT; -- Get the total count of rows SELECT MAX(id) INTO max_src_id FROM A.data; -- Loop until all rows are processed WHILE max_id < max_src_id DO -- Insert data in batches INSERT IGNORE INTO B.reading (Id, RecordedAtMT, SensorId, LocationId, SensorValue) SELECT data.id, data.datetime, device_sensor.sensor_id as sensor_id, data.location_id, data.value FROM A.data LEFT JOIN A.device_sensor ON data.device_sensor_id = device_sensor.id WHERE A.data.id > max_id ORDER BY A.data.id ASC LIMIT batch_size; -- Move to the next batch SELECT MAX(Id) INTO max_id FROM B.reading; END WHILE; END$$

如果您不需要将其写入二进制日志,您也可以使用 
set sql_log_bin = 0;

禁用它,假设定义者具有超级权限。

    

© www.soinside.com 2019 - 2024. All rights reserved.