必须确认字段映射严格一致:显式指定目标列名,核对数量、顺序、类型、NULL约束及数值精度;处理主键冲突用INSERT IGNORE或ON DUPLICATE KEY UPDATE;大批量插入需关闭autocommit、调优缓冲区并控制批量大小。

临时表数据插入正式表前,必须确认字段映射是否严格一致
直接 INSERT INTO ... SELECT 最常用,但出错往往是因为字段数量、顺序或类型不匹配。比如临时表有 5 列,正式表有 6 列(含自增主键),漏写列名就会报错 Column count doesn't match value count。
- 永远显式写出目标字段名,不要依赖
INSERT INTO table SELECT * - 用
DESCRIBE table_name或SHOW COLUMNS FROM table_name对比两边字段顺序和类型 - 注意 NULL 约束:正式表某列为
NOT NULL,而临时表对应列含NULL值,会触发Column 'xxx' cannot be null - 数值精度差异也要留意——比如临时表用
FLOAT,正式表是DECIMAL(10,2),可能因截断触发警告或失败
处理重复主键或唯一键冲突:ON DUPLICATE KEY UPDATE vs IGNORE
临时表常含已有记录,直接插入会报 Duplicate entry 'xxx' for key 'PRIMARY'。MySQL 下有两个主流应对方式,行为完全不同:
- 加
IGNORE:跳过冲突行,不报错也不更新,适合“只新增不覆盖”场景INSERT IGNORE INTO real_table (id, name, status) SELECT id, name, status FROM temp_table; - 用
ON DUPLICATE KEY UPDATE:冲突时更新指定字段,适合“存在则更新,不存在则插入”INSERT INTO real_table (id, name, status) SELECT id, name, status FROM temp_table ON DUPLICATE KEY UPDATE status = VALUES(status), name = VALUES(name); - 注意
VALUES(col)指的是本次SELECT中该列的值,不是原表当前值 - PostgreSQL 用
ON CONFLICT DO UPDATE,语法不同,不能直接套用 MySQL 写法
大批量插入时,关掉 autocommit + 调大 bulk_insert_buffer_size 更有效
插入几万行以上,逐条或默认事务提交会严重拖慢速度。关键不是换 ORM 方法,而是控制事务粒度和缓冲区:
- 先执行
SET autocommit = 0;,再批量插入,最后COMMIT; - 单次
INSERT尽量塞够 1000–5000 行(太多易 OOM,太少事务开销高)INSERT INTO real_table (...) VALUES (...), (...), (...); - 确认
bulk_insert_buffer_size足够(尤其 MyISAM 表),默认值常偏小,可临时调高:SET SESSION bulk_insert_buffer_size = 1024*1024*64; - InnoDB 表还要留意
innodb_log_file_size和innodb_buffer_pool_size,否则大量写入可能卡在刷日志或页淘汰上
临时表是 TEMPORARY 还是普通表,影响权限和可见性
很多人以为 CREATE TEMPORARY TABLE 是唯一“临时”方式,其实只是会话级自动清理。真正要注意的是权限和跨会话问题:
-
TEMPORARY表只能被当前连接访问,其他会话看不见,也不能被INSERT ... SELECT引用(除非同会话内) - 更常见的是用普通表命名如
tmp_user_import_202405—— 这种必须确保你有对它的SELECT权限,且正式表有INSERT权限 - 如果用存储过程封装插入逻辑,记得检查 DEFINER 权限,否则可能报
EXECUTE command denied - 临时表名若含特殊字符或关键字(如
order、group),必须用反引号包裹:SELECT * FROM `tmp_order_data`;
实际跑之前,先用 SELECT COUNT() 和 SELECT FROM temp_table LIMIT 5 看一眼数据量和样例;再用 EXPLAIN INSERT ... SELECT(MySQL 8.0+ 支持)确认没走全表扫描。这些步骤省不了,尤其当正式表带索引或触发器时,行为可能和预期差很远。










