利用數(shù)據(jù)庫 LOAD DATA 特性實現(xiàn)數(shù)據(jù)批量寫入
引言
在開發(fā)應(yīng)用程序時,經(jīng)常會遇到需要向數(shù)據(jù)庫批量寫入大量數(shù)據(jù)的場景,如數(shù)據(jù)初始化、數(shù)據(jù)遷移或者從外部系統(tǒng)導入數(shù)據(jù)等。傳統(tǒng)的逐條插入方式在數(shù)據(jù)量較大時,性能會變得非常低下,因為每一次插入操作都需要與數(shù)據(jù)庫建立連接、進行 SQL 解析和執(zhí)行等一系列開銷較大的操作。
MyBatis-Plus 作為一款優(yōu)秀的 MyBatis 增強工具,為我們提供了多種數(shù)據(jù)操作方式,同時結(jié)合數(shù)據(jù)庫自身的特性,如LOAD DATA語句,可以極大地提升批量寫入數(shù)據(jù)的效率。
本文將詳細介紹如何使用 MyBatis-Plus 結(jié)合LOAD DATA特性來實現(xiàn)高效的數(shù)據(jù)批量寫入。
數(shù)據(jù)庫 LOAD DATA 特性介紹
LOAD DATA是 MySQL 等數(shù)據(jù)庫提供的一種高效的數(shù)據(jù)導入語句。它允許從一個文本文件中快速地將數(shù)據(jù)加載到數(shù)據(jù)庫表中。與傳統(tǒng)的 INSERT 語句相比,LOAD DATA具有以下優(yōu)勢:
- 速度快:LOAD DATA是基于文件系統(tǒng)的操作,直接將文件中的數(shù)據(jù)批量加載到數(shù)據(jù)庫表中,避免了多次網(wǎng)絡(luò)傳輸和 SQL 解析的開銷。在處理大量數(shù)據(jù)時,速度比逐條 INSERT 語句快很多倍。
- 減少事務(wù)開銷:傳統(tǒng)的 INSERT 操作如果放在一個事務(wù)中,隨著數(shù)據(jù)量的增加,事務(wù)的持續(xù)時間會變長,占用數(shù)據(jù)庫資源。而LOAD DATA可以在短時間內(nèi)完成大量數(shù)據(jù)的插入,減少了事務(wù)的持續(xù)時間,降低了鎖爭用的可能性。
例如,在 MySQL 中,LOAD DATA的基本語法如下:
LOAD DATA [LOCAL] INFILE 'file_name'
INTO TABLE table_name
[FIELDS TERMINATED BY 'field_separator' [OPTIONALLY] ENCLOSED BY 'enclosure_character']
[LINES TERMINATED BY 'line_separator']
[IGNORE number LINES]
[(column_list)]
其中,file_name是包含要導入數(shù)據(jù)的文本文件路徑;table_name是目標數(shù)據(jù)庫表;FIELDS TERMINATED BY指定字段之間的分隔符;LINES TERMINATED BY指定行之間的分隔符;IGNORE number LINES表示忽略文件開頭的指定行數(shù);(column_list)指定要導入數(shù)據(jù)對應(yīng)的表列。
實現(xiàn)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper">
<insert id="batchInsertByLoadData">
LOAD DATA LOCAL INFILE '/path/to/your/data/file.txt'
INTO TABLE user
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
(id, name, age)
</insert>
</mapper>
補充
MyBatis-Plus 的saveBatch方法是其提供的一種便捷的批量插入方式,內(nèi)部會根據(jù)配置的批量插入大?。J為 1000)將數(shù)據(jù)拆分成多個批次進行插入操作。
性能對比
- LOAD DATA:如前所述,它基于文件系統(tǒng)操作,直接將文件數(shù)據(jù)批量加載到數(shù)據(jù)庫表,避免了多次網(wǎng)絡(luò)傳輸和 SQL 解析,在處理大量數(shù)據(jù)(如數(shù)十萬條甚至更多)時,性能優(yōu)勢極其明顯,速度比逐條插入快數(shù)倍甚至數(shù)十倍。
- saveBatch:雖然它也實現(xiàn)了批量插入,通過將數(shù)據(jù)分批次發(fā)送到數(shù)據(jù)庫減少了連接次數(shù),但每一批次的數(shù)據(jù)仍需進行 SQL 解析和執(zhí)行等操作。在數(shù)據(jù)量較大時,相比LOAD DATA,性能會有較大差距。例如,當插入 10 萬條數(shù)據(jù)時,LOAD DATA可能只需要幾秒鐘,而saveBatch可能需要幾十秒甚至更長時間,具體時間取決于數(shù)據(jù)庫配置、服務(wù)器性能等因素。
適用場景
- LOAD DATA:適用于大規(guī)模數(shù)據(jù)的一次性導入,比如數(shù)據(jù)初始化、從外部系統(tǒng)進行全量數(shù)據(jù)遷移等場景。由于其對數(shù)據(jù)格式要求較為嚴格,且操作相對復(fù)雜,不太適合少量數(shù)據(jù)的頻繁插入。
- saveBatch:適用于數(shù)據(jù)量相對較?。ㄈ鐜浊l以內(nèi))或者對數(shù)據(jù)格式和操作靈活性要求較高的場景。例如,在日常業(yè)務(wù)中,當需要批量插入一些用戶操作記錄等少量數(shù)據(jù)時,saveBatch使用起來更加方便快捷。
最后
通過 MyBatis-Plus 結(jié)合數(shù)據(jù)庫的LOAD DATA特性以及使用其自帶的saveBatch方法,都可以實現(xiàn)數(shù)據(jù)的批量寫入,但兩者各有優(yōu)劣。在實際應(yīng)用中,開發(fā)者需要根據(jù)具體的業(yè)務(wù)場景、數(shù)據(jù)量大小、代碼復(fù)雜度要求以及事務(wù)控制等因素,綜合考慮選擇合適的方法。如果是處理大規(guī)模數(shù)據(jù)的一次性導入,LOAD DATA無疑是更好的選擇,能顯著提升性能;而對于少量數(shù)據(jù)的頻繁插入或者對開發(fā)效率要求較高的場景,saveBatch則更為合適。希望本文能為讀者在解決數(shù)據(jù)批量寫入問題時提供全面的參考和幫助,以便根據(jù)實際需求做出最優(yōu)決策。