一、业务场景
实际开发中经常遇到跨表数据迁移、数据备份、错题数据归集等场景:根据一批指定ID,从源表批量查询符合条件的数据,同步写入目标数据表,并且统一追加一批公共固定字段数据,实现批量数据复刻入库。
二、传统写法存在的性能痛点
常规开发思路为:循环查询单条数据、组装数据、逐条新增入库。这种方式在少量数据下差异不大,但当ID数量多、数据量级变大后,会出现严重的性能损耗。
该方案会产生多次代码与数据库的IO交互,查询、组装、入库分步执行,交互次数随数据量线性递增。频繁的数据库请求、网络传输、程序循环运算,极大占用服务器资源,执行效率极低,数据量越大性能短板越明显。
三、高性能解决方案
放弃各类编程语言通用的循环逐条读写模式,采用 MySQL 原生 INSERT INTO ... SELECT 批量语法,不依赖各语言循环组装、分批入库逻辑,一次性完成「数据查询、字段拼接、批量入库」全流程,适配 PHP、Java、Go、C#、ASP、Rust 等所有开发语言。
通过IN条件筛选指定数据源,查询源表数据的同时,直接拼接统一固定公共字段,整体一次性写入目标表,极简高效。
-- 【通用核心SQL】全语言适配,Java/Go/C#/ASP/Rust/PHP 均可直接调用执行
-- 适配所有后端语言,仅需根据语言规则拼接参数、执行SQL即可
-- 【通用核心SQL】全语言适配,Java/Go/C#/ASP/Rust/PHP 均可直接调用执行-- 适配所有后端语言,仅需根据语言规则拼接参数、执行SQL即可INSERT INTO 目标表(基础业务字段,create_ip,create_time,data_y,data_m,data_d,test_id,simulator_record_id)SELECT源表.基础业务字段,? AS create_ip,? AS create_time,? AS data_y,? AS data_m,? AS data_d,? AS test_id,? AS simulator_record_idFROM 源表WHERE 关联ID IN (?)-- 优势:所有语言无需写循环、数据组装逻辑,仅传参执行SQL即可
五、多语言实战代码示例(参数化安全写法)
以下所有示例均基于上方通用SQL,采用参数化预编译,杜绝SQL注入,可直接适配项目业务,无需改造核心逻辑。
1. PHP 实现
// 固定公共参数$params = [ '127.0.0.1', date('Y-m-d H:i:s'), date('Y'), date('m'), date('d'), 100, 2001];// 待筛选ID数组$ids = [1,2,3,4,5];$inStr = implode(',', $ids);// 执行原生SQL$sql = "INSERT INTO 目标表(基础业务字段,create_ip,create_time,data_y,data_m,data_d,test_id,simulator_record_id)SELECT 源表.基础业务字段,?,?,?,?,?,?,? FROM 源表 WHERE 关联ID IN ({$inStr})";Db::execute($sql, $params);
2. Java 实现(MyBatis)
// 封装参数Map<String, Object> paramMap = new HashMap<>();paramMap.put("createIp", "127.0.0.1");paramMap.put("createTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));paramMap.put("dataY", new SimpleDateFormat("yyyy").format(new Date()));paramMap.put("dataM", new SimpleDateFormat("MM").format(new Date()));paramMap.put("dataD", new SimpleDateFormat("dd").format(new Date()));paramMap.put("testId", 100);paramMap.put("simulatorRecordId", 2001);paramMap.put("idList", Arrays.asList(1,2,3,4,5));// Mapper层直接执行int batchInsert(Mapper paramMap);
<insert id="batchInsert">INSERT INTO 目标表(基础业务字段,create_ip,create_time,data_y,data_m,data_d,test_id,simulator_record_id)SELECT 源表.基础业务字段,#{createIp},#{createTime},#{dataY},#{dataM},#{dataD},#{testId},#{simulatorRecordId}FROM 源表 WHERE 关联ID IN<foreach collection="idList" open="(" close=")" separator="," item="id">#{id}</foreach></insert>
3. Go 实现(GORM)
import "gorm.io/gorm"// 定义参数createIp := "127.0.0.1"createTime := time.Now().Format("2006-01-02 15:04:05")dataY := time.Now().Format("2006")dataM := time.Now().Format("01")dataD := time.Now().Format("02")testId := 100simulatorRecordId := 2001idList := []int{1,2,3,4,5}// 批量执行迁移插入db.Exec(`INSERT INTO 目标表(基础业务字段,create_ip,create_time,data_y,data_m,data_d,test_id,simulator_record_id)SELECT 源表.基础业务字段,?,?,?,?,?,?,? FROM 源表 WHERE 关联ID IN (?)`,createIp, createTime, dataY, dataM, dataD, testId, simulatorRecordId, idList)
4. C# 实现(ADO.NET)
// 基础参数赋值string createIp = "127.0.0.1";string createTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");string dataY = DateTime.Now.ToString("yyyy");string dataM = DateTime.Now.ToString("MM");string dataD = DateTime.Now.ToString("dd");int testId = 100;int simulatorRecordId = 2001;List<int> ids = new List<int> { 1,2,3,4,5 };string inSql = string.Join(",", ids);string sql = @"INSERT INTO 目标表(基础业务字段,create_ip,create_time,data_y,data_m,data_d,test_id,simulator_record_id)SELECT 源表.基础业务字段,@ip,@time,@y,@m,@d,@test,@sim FROM 源表 WHERE 关联ID IN (" + inSql + ")";// 参数化执行SqlCommand cmd = new SqlCommand(sql, conn);cmd.Parameters.AddWithValue("@ip", createIp);cmd.Parameters.AddWithValue("@time", createTime);cmd.Parameters.AddWithValue("@y", dataY);cmd.Parameters.AddWithValue("@m", dataM);cmd.Parameters.AddWithValue("@d", dataD);cmd.Parameters.AddWithValue("@test", testId);cmd.Parameters.AddWithValue("@sim", simulatorRecordId);cmd.ExecuteNonQuery();
5. ASP 经典实现
<%' 基础参数Dim createIp,createTime,dataY,dataM,dataD,testId,simulatorRecordId,inStrcreateIp = "127.0.0.1"createTime = Year(Now)&"-"&Month(Now)&"-"&Day(Now)&" "&Hour(Now)&":"&Minute(Now)&":"&Second(Now)dataY = Year(Now)dataM = Month(Now)dataD = Day(Now)testId = 100simulatorRecordId = 2001inStr = "1,2,3,4,5"' 执行SQLDim sqlsql = "INSERT INTO 目标表(基础业务字段,create_ip,create_time,data_y,data_m,data_d,test_id,simulator_record_id) " & _"SELECT 源表.基础业务字段,'"&createIp&"','"&createTime&"','"&dataY&"','"&dataM&"','"&dataD&"',"&testId&","&simulatorRecordId& " FROM 源表 WHERE 关联ID IN ("&inStr&")"Conn.Execute(sql)%>
6. Rust 实现(sqlx)
use sqlx::mysql::MySqlPool;use chrono::Local;// 异步批量插入async fn batch_migrate(pool: &MySqlPool) -> Result<(), sqlx::Error> { let create_ip = "127.0.0.1"; let now = Local::now(); let create_time = now.format("%Y-%m-%d %H:%M:%S").to_string(); let data_y = now.format("%Y").to_string(); let data_m = now.format("%m").to_string(); let data_d = now.format("%d").to_string(); let test_id = 100; let simulator_record_id = 2001; let id_list = vec![1,2,3,4,5]; let in_str: Vec<String> = id_list.iter().map(|x| x.to_string()).collect(); let in_str = in_str.join(","); // 执行SQL sqlx::query(&format!(r#" INSERT INTO 目标表(基础业务字段,create_ip,create_time,data_y,data_m,data_d,test_id,simulator_record_id) SELECT 源表.基础业务字段,?,?,?,?,?,?,? FROM 源表 WHERE 关联ID IN ({}) "#, in_str)) .bind(create_ip) .bind(create_time) .bind(data_y) .bind(data_m) .bind(data_d) .bind(test_id) .bind(simulator_record_id) .execute(pool) .await?; Ok(())}
-- 优势:所有语言无需写循环、数据组装逻辑,仅传参执行SQL即可
四、方案核心优势
1. 极致减少IO交互,性能大幅提升
传统写法是N次查询+N次入库,双重循环消耗资源;本方案仅执行单次数据库交互,所有数据筛选、字段拼接、入库操作均在数据库层完成,彻底规避PHP与数据库频繁通讯的性能开销。
2. 数据库层原生执行,效率更高
INSERT SELECT 是MySQL原生优化语法,底层执行效率远高于PHP循环组装数据。数据量越大,新旧方案的性能差距越悬殊,海量数据批量迁移优势极其明显。
3. 代码简洁、维护性强
无需各语言编写复杂循环、数据组装、分片批量等冗余逻辑,核心能力完全依托MySQL原生语法实现,代码极简、通用性极强,同时规避了多语言循环超时、内存溢出、分片异常等常见问题,项目维护性与稳定性大幅提升。
-
人人皆为创造者 每个人都是使用者,也是创造者;是数字世界的消费者,更是价值的生产者与分享者。在智能时代的浪潮里,单打独斗的发展模式早已落幕,唯有开放连接、创意共创、利益共享,才能让个体价值汇聚成生态合力,让技术与创意双向奔赴,实现平台与伙伴的快速成长、共赢致远。
原创应该获得永久分成 原创创意共创、永久收益分成,是东方仙盟始终坚守的核心理念。我们坚信,每一份原创智慧都值得被尊重与回馈,以永久分成锚定共创初心,让创意者长期享有价值红利,携手万千伙伴向着科技星辰大海笃定前行,拥抱硅基 生命与数字智能交融的未来,共筑跨越时代的数字文明共同体。
-
东方仙盟
东方仙盟:拥抱知识开源,共筑数字新生态
在全球化与数字化浪潮中,东方仙盟始终秉持开放协作、知识共享的理念,积极拥抱开源技术与开放标准。我们相信,唯有打破技术壁垒、汇聚全球智慧,才能真正推动行业的可持续发展。
开源赋能中小商户:通过将前端异常检测、跨系统数据互联等核心能力开源化,东方仙盟为全球中小商户提供了低成本、高可靠的技术解决方案,让更多商家能够平等享受数字转型的红利。共建行业标准:我们积极参与国际技术社区,与全球开发者、合作伙伴共同制定开放协议与技术规范,推动跨境零售、文旅、餐饮等多业态的系统互联互通,构建更加公平、高效的数字生态。知识普惠,共促发展:通过开源社区、技术文档与培训体系,东方仙盟致力于将前沿技术转化为可落地的行业实践,赋能全球合作伙伴,共同培育创新人才,推动数字经济 的普惠式增长
阿雪技术观
在科技发展浪潮中,我们不妨积极投身技术共享。不满足于做受益者,更要主动担当贡献者。无论是分享代码、撰写技术博客,还是参与开源项目维护改进,每一个微小举动都可能蕴含推动技术进步的巨大能量。东方仙盟是汇聚力量的天地,我们携手在此探索硅基生命,为科技进步添砖加瓦。
Hey folks, in this wild tech - driven world, why not dive headfirst into the whole tech - sharing scene? Don't just be the one reaping all the benefits; step up and be a contributor too. Whether you're tossing out your code snippets, hammering out some tech blogs, or getting your hands dirty with maintaining and sprucing up open - source projects, every little thing you do might just end up being a massive force that pushes tech forward. And guess what? The Eastern FairyAlliance is this awesome place where we all come together. We're gonna team up and explore the whole silicon - based life thing, and in the process, we'll be fueling the growth of technology.
开通方法
关注我们
营销资讯:抖音运营,微信公众号运营,小红书运营
网站运营:安全、备案、申请网站,漏洞扫描,数字证书
开发:开发技巧、热点技术,人工智能,数据分析,数据优化,docker
数据服务:数据恢复,数据安全,数据融合,数据异地容灾,数据优化,数据自动备份、数据清洗
人工智能:智能物联网,智慧大屏幕,OCR,智慧刷脸,语音交互,智能机器人,数字生命,数字人,大模型,本地化,边缘化智能(手机模型)
支付:微信支付服务商,支付支付服务商,刷脸支付
安全服务:WAF安全,网安扫描,漏洞扫描,安全补丁,防火墙定制
智慧大屏:物资耗材大屏幕,单位用餐大数据,智慧场馆大屏,销售大屏幕,智慧社区大屏幕,大厅查询机,景区自助机
智慧酒店:酒店系统、酒店押金、酒店房价牌、酒店门锁、布草系统
行业软件:酒店、餐饮、便利店,美发、超市,批发,景区门票,道闸,堂食,配送系统,烘焙系统,健身,美容系统,月子中心系统
物联网:智能衣柜,足浴店衣柜,售货柜,酒店自助入住机
国产化:uos系统答疑,国产软件开发,国产服务器配置,docker
一体化:酒店一体化(闸机,酒店系统,餐饮系统,售票,布草,无人酒店,在线订房),景区一体化(门票、餐饮、住宿、押金、超市、药店、商铺租赁,通车系统,售票大厅,大屏幕,无人景区,景区自助机)

