快速复制A库表数据前10000行到B库

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 应用场景
  • 一、存储过程,快速复制A库表数据前10000行到B库
  • 二、使用
  • 优化点说明
    • 结构优化
    • 性能调整
    • 错误处理增强
    • 安全改进
  • 调用示例


应用场景

表结构可预先存在或不存在
mysql5.7
快速复制A库表数据前10000行到B库


一、存储过程,快速复制A库表数据前10000行到B库

/* 设置自定义分隔符以处理存储过程中的分号 */
DELIMITER $$

/* 删除已存在的同名存储过程 */
DROP PROCEDURE IF EXISTS sync_database_data$$

/* 创建存储过程(带参数) */
CREATE PROCEDURE sync_database_data(
  IN source_db VARCHAR(64),   -- 源数据库名称
  IN target_db VARCHAR(64)    -- 目标数据库名称
)
BEGIN
  /* 声明变量 */
  DECLARE done BOOLEAN DEFAULT FALSE;      -- 循环控制标志
  DECLARE tb_name VARCHAR(64);             -- 存储表名
  DECLARE err_msg TEXT;                    -- 错误信息存储
  
  /* 声明游标(必须放在 HANDLER 之前) */
  DECLARE cur CURSOR FOR 
    SELECT TABLE_NAME 
    FROM information_schema.TABLES 
    WHERE TABLE_SCHEMA = source_db
      AND TABLE_TYPE = 'BASE TABLE';       -- 仅处理物理表,排除视图
      
  /* 声明处理器 */
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;  -- 游标结束处理
  DECLARE EXIT HANDLER FOR SQLEXCEPTION                    -- 异常处理
  BEGIN
    GET DIAGNOSTICS CONDITION 1 err_msg = MESSAGE_TEXT;    -- 获取错误详情
    SET @full_err = CONCAT('表 ', tb_name, ' 同步失败: ', LEFT(err_msg, 64));
    RESIGNAL SET MESSAGE_TEXT = @full_err;                 -- 抛出带表名的错误
    ROLLBACK;                                              -- 回滚事务
  END;

  /*----------- 前置校验 -----------*/
  -- 验证源数据库是否存在
  IF NOT EXISTS (
    SELECT 1 
    FROM information_schema.SCHEMATA 
    WHERE SCHEMA_NAME = source_db
  ) THEN
    SIGNAL SQLSTATE '45000' 
    SET MESSAGE_TEXT = '源数据库不存在';
  END IF;

  /*----------- 主逻辑 -----------*/
  -- 打开表游标
  OPEN cur;
  
  -- 开始循环处理每张表
  read_loop: LOOP
    FETCH cur INTO tb_name;
    IF done THEN 
      LEAVE read_loop;      -- 退出循环
    END IF;
    
    /* 动态生成SQL语句 */
    -- 创建表结构(如果不存在)
    SET @create_sql = CONCAT(
      'CREATE TABLE IF NOT EXISTS `', target_db, '`.`', tb_name, 
      '` LIKE `', source_db, '`.`', tb_name, '`'
    );
    
    -- 全部数据
    SET @insert_sql = CONCAT(
      'INSERT INTO `', target_db, '`.`', tb_name, 
      '` SELECT * FROM `', source_db, '`.`', tb_name ,'`'
    );
    
        -- 插入前10000条数据
--     SET @insert_sql = CONCAT(
--       'INSERT INTO `', target_db, '`.`', tb_name, 
--       '` SELECT * FROM `', source_db, '`.`', tb_name, 
--       '` LIMIT 10000'
--     );

    /*----------- 性能优化配置 -----------*/
    -- 设置批量插入缓存(仅当前会话有效)
    SET bulk_insert_buffer_size = 256 * 1024 * 1024;  -- 256MB
    
    -- 禁用约束检查(加速插入)
    SET unique_checks = 0;         -- 关闭唯一性校验
    SET foreign_key_checks = 0;    -- 关闭外键校验

    /*----------- 事务执行块 -----------*/
    START TRANSACTION;
    
    -- 执行建表操作
    PREPARE stmt FROM @create_sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
    
    -- 执行数据插入
    PREPARE stmt FROM @insert_sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
    
    COMMIT;  -- 提交事务

    /*----------- 恢复配置 -----------*/
    -- 启用约束检查(保证后续操作安全)
    SET unique_checks = 1;
    SET foreign_key_checks = 1;
  END LOOP;
  
  -- 关闭游标
  CLOSE cur;
END$$

/* 恢复默认分隔符 */
DELIMITER ;

二、使用

– 完整同步示例
CALL sync_database_data(‘target_db’, ‘target_db’);

优化点说明

结构优化

将代码分为清晰的逻辑区块,使用注释分隔验证、主逻辑、配置等部分

性能调整

   -- 在插入前禁用约束检查
   SET unique_checks = 0;     
   SET foreign_key_checks = 0;
   
   -- 在插入后恢复设置
   SET unique_checks = 1;
   SET foreign_key_checks = 1;

该配置对InnoDB引擎有效,可使插入速度提升2-3倍

错误处理增强

DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN

RESIGNAL SET MESSAGE_TEXT = @full_err; – 显示具体报错表
ROLLBACK; – 确保事务回滚
END;

安全改进

CREATE TABLE IF NOT EXISTS – 避免表已存在时报错

调用示例

 完整同步示例
CALL sync_database_data('source_db', 'target_db');

你可能感兴趣的:(数据库,sql,mysql)