0

0

如何在SQL中实现批量插入?INSERTINTO的进阶用法

蓮花仙者

蓮花仙者

发布时间:2025-09-04 20:24:01

|

415人浏览过

|

来源于php中文网

原创

批量插入通过单条INSERT语句插入多行数据,减少网络往返和数据库解析开销,显著提升性能;可结合SELECT或UNION ALL实现动态数据插入,并利用ON DUPLICATE KEY UPDATE、ON CONFLICT或MERGE处理重复数据;超大规模导入推荐使用LOAD DATA INFILE、COPY、BULK INSERT等数据库专用工具以实现高效数据加载。

如何在sql中实现批量插入?insertinto的进阶用法

在SQL中实现批量插入,最直接且常用的方法就是在一个

INSERT INTO
语句中,通过逗号分隔的方式一次性插入多行数据。这远比循环执行单条插入语句高效得多,是优化数据库写入性能的关键一步。

解决方案

批量插入的核心在于将多个数据行作为单个

INSERT
语句的一部分提交给数据库。这极大地减少了客户端与服务器之间的网络往返次数,也让数据库有机会进行更高效的内部处理。

最常见的形式是使用

INSERT INTO table_name (column1, column2, ...)
后跟
VALUES (value1_row1, value2_row1, ...), (value1_row2, value2_row2, ...), ...

例如,假设我们有一个

products
表,包含
id
,
name
,
price
字段:

INSERT INTO products (id, name, price) VALUES
(1, 'Laptop', 1200.00),
(2, 'Mouse', 25.00),
(3, 'Keyboard', 75.00),
(4, 'Monitor', 300.00);

这种写法,一次性就将四条产品数据插入到了表中。我个人觉得,当你需要插入的数据量不是特别巨大,但又远超单条时,这种方式是最直观也最容易实现的选择。它不仅代码看起来简洁,实际执行效率也得到了显著提升。

除了直接的

VALUES
语法,另一种进阶用法是结合
SELECT
语句。当你需要从另一个表或者一个查询结果中插入多行数据时,可以使用
INSERT INTO ... SELECT ...
的语法。例如:

INSERT INTO new_products (id, name, price)
SELECT p.id, p.name, p.price FROM old_products p WHERE p.status = 'new';

如果数据源是动态生成的,或者需要合并多个独立的数据集,你甚至可以利用

UNION ALL
来构建一个虚拟表进行批量插入:

INSERT INTO orders (order_id, customer_id, amount) VALUES
(101, 1, 50.00),
(102, 2, 120.00)
UNION ALL
SELECT 103, 3, 75.00; -- 假设这部分数据是动态生成的

当然,上面这个

UNION ALL
的例子更多是演示其组合数据的能力,实际应用中,
VALUES
列表本身就足以处理静态的多行数据。

为什么批量插入比单条插入效率更高?

这其实反映了一个核心的数据库优化思想:减少开销。在我看来,批量插入之所以能带来显著的性能提升,主要有几个方面的原因:

首先,是网络通信的开销。每次执行单条

INSERT
语句,客户端都需要与数据库服务器进行一次完整的网络往返(Round Trip Time, RTT)。这包括发送SQL语句、等待服务器处理、接收执行结果。如果插入1000条数据,你就需要1000次这样的往返。而批量插入,无论插入多少行,通常只需要一次或少数几次网络往返。想想看,这就好比你寄快递,是把1000件小包裹一次性打包寄出去,还是每件包裹单独跑一趟快递公司,效率高下立判。

其次,数据库内部的处理效率也更高。数据库收到SQL语句后,需要进行解析、优化、生成执行计划。对于批量插入,数据库只需要对一个大的

INSERT
语句进行一次解析和优化。而对于1000条单条
INSERT
,它就得重复这1000次。这种重复的解析和优化本身就是一种资源消耗。

再者,是事务处理和日志记录的开销。大多数数据库操作都发生在事务中。即使你没有显式开启事务,每条

INSERT
也可能隐式地形成一个小的事务。这意味着每次插入都需要记录事务日志,进行锁管理等。批量插入可以将多行数据作为一个更大的事务单元来处理,从而减少了事务提交和日志写入的频率,使得I/O操作更加集中和高效。磁盘I/O的优化对于数据库性能至关重要,批量写入通常能更好地利用磁盘的顺序写入特性,而不是零散的随机写入。

批量插入时如何处理错误或重复数据?

这块其实挺让人头疼的,尤其是在数据源不那么干净的时候。批量插入最大的挑战之一就是数据校验和错误处理。如果批量数据中有一行数据违反了表的约束(比如主键冲突、非空字段为空、数据类型不匹配等),整个批量操作可能就会失败,或者行为变得不可预测。不同数据库对此有不同的处理策略和语法。

在MySQL中,如果你希望在遇到主键或唯一索引冲突时,不是报错而是更新现有记录,可以使用

INSERT ... ON DUPLICATE KEY UPDATE
。这在很多“ upsert ”(更新或插入)场景下非常实用:

扣子编程
扣子编程

扣子推出的AI编程开发工具

下载
INSERT INTO users (id, name, email) VALUES
(1, 'Alice', 'alice@example.com'),
(2, 'Bob', 'bob@example.com')
ON DUPLICATE KEY UPDATE
name = VALUES(name),
email = VALUES(email);

如果

id=1
的记录已经存在,那么它的
name
email
就会被更新为新值。如果只是想忽略冲突行,可以使用
INSERT IGNORE INTO ...
,它会跳过那些导致唯一键冲突的行,继续插入其他行。

对于PostgreSQL,它提供了

INSERT ... ON CONFLICT (column_name) DO UPDATE SET ...
DO NOTHING
的语法,功能与MySQL的
ON DUPLICATE KEY UPDATE
类似,但更加灵活,你可以指定冲突的列:

INSERT INTO products (id, name, price) VALUES
(1, 'Laptop', 1200.00),
(2, 'Mouse', 25.00)
ON CONFLICT (id) DO UPDATE SET
name = EXCLUDED.name,
price = EXCLUDED.price;

这里的

EXCLUDED
关键字引用的是将要插入但发生冲突的行的数据。

在SQL Server和Oracle等数据库中,

MERGE
语句是一个更强大的工具,它允许你根据源表和目标表之间的匹配条件,执行插入、更新或删除操作。这对于复杂的批量数据同步和处理非常有用。

-- SQL Server 示例
MERGE INTO TargetTable AS T
USING SourceTable AS S
ON T.id = S.id
WHEN MATCHED THEN
    UPDATE SET T.name = S.name, T.value = S.value
WHEN NOT MATCHED THEN
    INSERT (id, name, value) VALUES (S.id, S.name, S.value);

从应用程序层面看,在执行批量插入前对数据进行预校验也是一种常见的做法。比如,你可以先查询数据库中已存在的记录,过滤掉重复的数据,或者在内存中对数据进行清洗和去重。这种方式虽然增加了应用程序的逻辑复杂性,但能更好地控制数据质量,并且在某些情况下可以避免数据库层面的错误处理开销。我个人觉得,对于关键业务数据,这种“双保险”的策略往往更稳妥。

如何利用数据库特定功能实现超大规模数据导入?

当数据量达到百万、千万甚至亿级别时,即使是

INSERT INTO ... VALUES (...)
这种批量插入方式,也可能显得不够高效。这时,就需要考虑利用数据库系统提供的专门用于高速数据导入的功能了。这些功能通常绕过了标准的SQL解析和事务处理的一些开销,直接与存储引擎交互,从而实现极致的导入速度。

以MySQL为例,它提供了

LOAD DATA INFILE
语句。这个命令允许你从一个文本文件(如CSV文件)中直接将数据加载到表中。它的速度非常快,因为它避免了SQL语句的解析开销,并且可以配置多种选项来处理数据格式、错误等。

LOAD DATA INFILE '/path/to/your/data.csv'
INTO TABLE your_table
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 ROWS; -- 如果文件有标题行,可以忽略第一行

需要注意的是,

LOAD DATA INFILE
通常要求文件位于数据库服务器可访问的路径上,并且需要特定的文件权限。

PostgreSQL也有类似的机制,叫做

COPY FROM
。这同样是一个非常高效的数据导入命令,可以从文件、标准输入或外部程序中读取数据。

COPY your_table (column1, column2, column3)
FROM '/path/to/your/data.csv'
DELIMITER ','
CSV HEADER; -- 表示文件包含标题行

COPY
命令在PostgreSQL中是导入大量数据的首选方式,它的性能表现非常出色。

SQL Server则有

BULK INSERT
命令,以及更强大的SQL Server Integration Services (SSIS) 工具,后者可以处理更复杂的数据转换和加载场景。

BULK INSERT your_table
FROM '/path/to/your/data.csv'
WITH (
    FIELDTERMINATOR = ',',
    ROWTERMINATOR = '\n',
    FIRSTROW = 2 -- 如果有标题行
);

Oracle数据库则提供了SQL*Loader工具,这是一个命令行实用程序,专门用于将外部数据文件加载到Oracle数据库表中。它功能强大,支持复杂的加载逻辑和数据转换。

这些数据库特定的导入工具,在我看来,是处理真正意义上的“大数据量”导入的利器。它们的设计目标就是最大化吞吐量,通常会提供更细粒度的控制,例如并行加载、错误日志记录、跳过指定行等。当然,使用这些工具通常意味着你需要对数据文件的格式有严格的控制,并且可能需要一些额外的配置或权限。但在面对GB甚至TB级别的数据导入任务时,它们带来的性能提升是任何

INSERT INTO VALUES
都无法比拟的。

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

通义千问
通义千问

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

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

727

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

328

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

350

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

1243

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

360

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

821

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

581

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

423

2024.04.29

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

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

158

2026.01.28

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Rust 教程
Rust 教程

共28课时 | 5万人学习

Kotlin 教程
Kotlin 教程

共23课时 | 3万人学习

Go 教程
Go 教程

共32课时 | 4.3万人学习

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

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