0

0

Laravel大数据批量操作慢如蜗牛?yadakhov/insert-on-duplicate-key助你轻松解决,效率飙升!

心靈之曲

心靈之曲

发布时间:2025-09-26 12:24:30

|

435人浏览过

|

来源于php中文网

原创

laravel大数据批量操作慢如蜗牛?yadakhov/insert-on-duplicate-key助你轻松解决,效率飙升!

可以通过一下地址学习composer学习地址

在日常的 Web 开发中,我们经常会遇到需要批量处理数据库记录的场景。比如,从外部系统同步用户数据,或者在导入 Excel 文件时更新现有记录并插入新记录。对于 Laravel 开发者来说,你可能会第一时间想到使用 Eloquent 提供的 updateOrCreate() 方法。然而,当你面对成百上千甚至上万条数据时,问题就来了。

批量操作的“痛点”:效率与优雅的抉择

updateOrCreate() 方法固然方便,但它本质上是对单条记录进行操作:先查询是否存在,再决定更新还是插入。这意味着,如果你有 N 条数据需要处理,它将执行至少 N 条数据库查询(N 次 SELECT + N 次 INSERT/UPDATE),这被称为 N+1 查询问题。当数据量庞大时,这种模式会导致:

  1. 性能急剧下降: 每次数据库交互都有开销,N 次查询会显著增加请求处理时间。
  2. 数据库压力增大: 大量短小的查询请求会给数据库服务器带来不必要的负担。
  3. 代码不够“优雅”: 虽然 updateOrCreate() 简洁,但为了批量操作而将其放入循环中,总感觉不是最优解。

我曾在一个数据同步项目中深受其害。每天需要同步数万条用户数据,使用 updateOrCreate() 后,同步过程耗时数小时,且经常导致数据库连接超时。我尝试过手动拼接 SQL 语句,但那不仅繁琐易错,还破坏了 Eloquent 的便利性。难道就没有一种既高效又符合 Laravel 风格的解决方案吗?

救星登场:yadakhov/insert-on-duplicate-key

正当我为此苦恼时,我发现了 yadakhov/insert-on-duplicate-key 这个 Composer 包。它完美地解决了我的困境,提供了一种在 Laravel 中优雅地实现 MySQL INSERT ... ON DUPLICATE KEY UPDATE 批量操作的方案。

什么是 INSERT ... ON DUPLICATE KEY UPDATE

这是 MySQL 数据库特有的一个强大功能。它允许你在尝试插入多条记录时,如果遇到主键或唯一索引冲突,则不报错,而是执行指定的更新操作。这样,我们就能在一个 SQL 语句中完成“插入或更新”的逻辑,将 N 次数据库操作优化为仅仅 1 次!

如何使用 Composer 引入它?

使用 yadakhov/insert-on-duplicate-key 非常简单,只需通过 Composer 安装即可:

composer require yadakhov/insert-on-duplicate-key

安装完成后,你需要在你的 Eloquent 模型中使用它提供的 InsertOnDuplicateKey trait。

use Illuminate\Database\Eloquent\Model;
use Yadakhov\InsertOnDuplicateKey;

class User extends Model
{
    // 引入这个 trait,即可拥有批量操作的能力
    use InsertOnDuplicateKey;

    protected $fillable = ['id', 'email', 'name', 'heritage']; // 确保你的模型有 fillable 字段
}

告别 N+1 查询:批量插入与更新的实践

现在,你的 User 模型就具备了强大的批量操作能力。

1. 批量插入或更新(insertOnDuplicateKey

这是最常用的功能。它接受一个包含多个数组的数组,每个内层数组代表一条记录的数据。

码上飞
码上飞

码上飞(CodeFlying) 是一款AI自动化开发平台,通过自然语言描述即可自动生成完整应用程序。

下载
use Carbon\Carbon; // 如果你需要处理时间戳

$users = [
    ['id' => 1, 'email' => 'user1@example.com', 'name' => 'User One', 'created_at' => Carbon::now(), 'updated_at' => Carbon::now()],
    ['id' => 2, 'email' => 'user2@example.com', 'name' => 'User Two', 'created_at' => Carbon::now(), 'updated_at' => Carbon::now()],
    ['id' => 3, 'email' => 'user3@example.com', 'name' => 'User Three', 'created_at' => Carbon::now(), 'updated_at' => Carbon::now()],
];

// 默认情况下,如果发生冲突,所有字段都会被更新(除了主键)
User::insertOnDuplicateKey($users);

/*
会生成类似这样的 SQL 语句:
INSERT INTO `users`(`id`,`email`,`name`,`created_at`,`updated_at`) VALUES
(1,'user1@example.com','User One',...), (2,'user2@example.com','User Two',...), (3,'user3@example.com','User Three',...)
ON DUPLICATE KEY UPDATE `id` = VALUES(`id`), `email` = VALUES(`email`), `name` = VALUES(`name`), `created_at` = VALUES(`created_at`), `updated_at` = VALUES(`updated_at`)
*/

重要提示: 传递给 insertOnDuplicateKey 的数据数组,其内部键的顺序必须保持一致。因为底层实现会使用 array_values() 来获取值。

如果你只想更新部分字段,可以作为第二个参数传递:

// 如果发生冲突,只更新 email 字段
User::insertOnDuplicateKey($users, ['email']);

/*
SQL 语句将变为:
... ON DUPLICATE KEY UPDATE `email` = VALUES(`email`)
*/

更高级的用法是,你可以使用 DB::raw() 来进行复杂的更新操作,例如累加一个数字字段:

use Illuminate\Support\Facades\DB;

$usersWithHeritage = [
    ['id' => 1, 'name' => 'User One', 'heritage' => 1000, 'created_at' => Carbon::now(), 'updated_at' => Carbon::now()],
    ['id' => 2, 'name' => 'User Two', 'heritage' => 2000, 'created_at' => Carbon::now(), 'updated_at' => Carbon::now()],
];

// 如果 id 冲突,则将 heritage 字段累加
User::insertOnDuplicateKey($usersWithHeritage, ['heritage' => DB::raw('`heritage` + VALUES(`heritage`)')]);

/*
SQL 语句将变为:
... ON DUPLICATE KEY UPDATE `heritage` = `heritage` + VALUES(`heritage`)
*/

请注意,created_atupdated_at 字段不会自动处理。你需要手动在数据数组中提供它们的值,就像上面的示例一样。

2. 批量插入忽略冲突(insertIgnore

如果你只希望插入新记录,而忽略任何与现有记录的冲突,可以使用 insertIgnore

User::insertIgnore($users);

/*
会生成类似这样的 SQL 语句:
INSERT IGNORE INTO `users`(`id`,`email`,`name`) VALUES (...)
*/

3. 批量替换记录(replace

REPLACE INTO 语句会删除旧记录并插入新记录(如果存在冲突)。

User::replace($users);

/*
会生成类似这样的 SQL 语句:
REPLACE INTO `users`(`id`,`email`,`name`) VALUES (...)
*/

优势与实际应用效果

使用 yadakhov/insert-on-duplicate-key 后,我项目的同步时间从数小时缩短到了几分钟,数据库负载也显著降低。它的优势显而易见:

  • 性能飞跃: 将大量的单条 SQL 操作合并为一条高效的批量 SQL 语句,极大提升了数据处理速度。
  • 代码简洁: 无需手动构建复杂的 SQL 语句,通过 Eloquent 模型的链式调用即可完成。
  • 维护性高: 代码逻辑清晰,易于理解和维护。
  • 场景丰富: 不仅支持简单的插入/更新,还能处理复杂的更新逻辑(如数值累加)。
  • 无缝集成: 作为 Eloquent trait,它完美融入 Laravel 生态,让你的代码保持一致的风格。

总结

yadakhov/insert-on-duplicate-key 是 Laravel 开发者处理 MySQL 批量数据同步和更新的利器。它通过利用数据库本身的优化能力,彻底解决了传统方法中 N+1 查询带来的性能瓶颈。如果你正在为 Laravel 项目中大数据量的插入或更新操作效率低下而烦恼,那么这个 Composer 包绝对值得你一试。它将让你的代码更高效、更健壮,同时保持 Laravel 开发的优雅与便捷。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
laravel组件介绍
laravel组件介绍

laravel 提供了丰富的组件,包括身份验证、模板引擎、缓存、命令行工具、数据库交互、对象关系映射器、事件处理、文件操作、电子邮件发送、队列管理和数据验证。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

320

2024.04.09

laravel中间件介绍
laravel中间件介绍

laravel 中间件分为五种类型:全局、路由、组、终止和自定。想了解更多laravel中间件的相关内容,可以阅读本专题下面的文章。

278

2024.04.09

laravel使用的设计模式有哪些
laravel使用的设计模式有哪些

laravel使用的设计模式有:1、单例模式;2、工厂方法模式;3、建造者模式;4、适配器模式;5、装饰器模式;6、策略模式;7、观察者模式。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

373

2024.04.09

thinkphp和laravel哪个简单
thinkphp和laravel哪个简单

对于初学者来说,laravel 的入门门槛较低,更易上手,原因包括:1. 更简单的安装和配置;2. 丰富的文档和社区支持;3. 简洁易懂的语法和 api;4. 平缓的学习曲线。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

374

2024.04.10

laravel入门教程
laravel入门教程

本专题整合了laravel入门教程,想了解更多详细内容,请阅读专题下面的文章。

85

2025.08.05

laravel实战教程
laravel实战教程

本专题整合了laravel实战教程,阅读专题下面的文章了解更多详细内容。

65

2025.08.05

laravel面试题
laravel面试题

本专题整合了laravel面试题相关内容,阅读专题下面的文章了解更多详细内容。

68

2025.08.05

composer是什么插件
composer是什么插件

Composer是一个PHP的依赖管理工具,它可以帮助开发者在PHP项目中管理和安装依赖的库文件。Composer通过一个中央化的存储库来管理所有的依赖库文件,这个存储库包含了各种可用的依赖库的信息和版本信息。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

154

2023.12.25

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

158

2026.01.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
第二十四期_PHP8编程
第二十四期_PHP8编程

共86课时 | 3.4万人学习

成为PHP架构师-自制PHP框架
成为PHP架构师-自制PHP框架

共28课时 | 2.5万人学习

第二十三期_PHP编程
第二十三期_PHP编程

共93课时 | 6.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号