MySQL 批量插入的原理和實戰(zhàn)方法(快速提升大數(shù)據(jù)導入效率)
在日常開發(fā)中,我們經(jīng)常需要將大量數(shù)據(jù)批量插入到 MySQL 數(shù)據(jù)庫中。然而,逐行插入(單條執(zhí)行 INSERT INTO)的方式效率較低,尤其在處理大規(guī)模數(shù)據(jù)時,會導致性能瓶頸。為了解決這個問題,我們可以使用批量插入技術,顯著提升數(shù)據(jù)插入效率。本文將介紹批量插入的原理、實現(xiàn)方法,并結(jié)合 Python 和 PyMySQL 庫提供詳細的實戰(zhàn)示例。
一、批量插入的優(yōu)勢
批量插入數(shù)據(jù)有以下幾個優(yōu)點:
- 減少網(wǎng)絡交互:批量插入一次性傳輸多條記錄,減少客戶端與數(shù)據(jù)庫之間的網(wǎng)絡通信次數(shù)。
- 提高事務效率:批量插入可以減少事務的提交次數(shù),從而降低事務管理的開銷。
- 提高插入性能:批量插入可以有效地降低數(shù)據(jù)庫的鎖定資源時間,使插入操作更高效。
二、MySQL 表的創(chuàng)建示例
我們以學生信息表為例,假設有如下的表結(jié)構(gòu):
CREATE TABLE students (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100),
age INT,
gender ENUM('M', 'F'),
grade VARCHAR(10)
);
表 students 用于存儲學生的基本信息,包括 id(主鍵),name(姓名),age(年齡),gender(性別),以及 grade(成績)。
三、Python 實現(xiàn)批量插入
接下來,我們使用 Python 的 PyMySQL 庫來連接 MySQL,并實現(xiàn)批量插入數(shù)據(jù)。
1. 安裝 PyMySQL 和 Faker 庫
首先,確保已經(jīng)安裝了 PyMySQL 和 Faker 庫。如果尚未安裝,可以使用以下命令進行安裝:
pip install pymysql faker
2. 生成 1 萬條隨機的學生數(shù)據(jù)
使用 Faker 庫生成隨機的學生信息數(shù)據(jù),包括姓名、年齡、性別和成績。以下是生成數(shù)據(jù)的代碼:
import random
from faker import Faker
# 初始化 Faker
fake = Faker()
# 隨機生成學生數(shù)據(jù)
def generate_random_students(num_records=10000):
students_data = []
for _ in range(num_records):
name = fake.name()
age = random.randint(18, 25) # 隨機年齡在 18 到 25 歲之間
gender = random.choice(['M', 'F']) # 隨機選擇性別
grade = random.choice(['A', 'B', 'C', 'D', 'F']) # 隨機選擇成績
students_data.append((name, age, gender, grade))
return students_data
# 生成 1 萬條學生數(shù)據(jù)
students_data = generate_random_students(10000)
# 輸出前 5 條數(shù)據(jù)查看
for student in students_data[:5]:
print(student)3. 批量插入數(shù)據(jù)到 MySQL
批量插入的核心思路是將數(shù)據(jù)分成若干批次,使用 executemany 方法執(zhí)行批量插入操作。下面是批量插入的完整代碼:
import pymysql
from tqdm import tqdm
# 創(chuàng)建數(shù)據(jù)庫連接
connection = pymysql.connect(
host='localhost',
user='your_username',
password='your_password',
database='your_database',
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor
)
# 批量插入的批次大小
BATCH_SIZE = 1000
try:
with connection.cursor() as cursor:
batch = []
for student in tqdm(students_data, total=len(students_data)):
batch.append(student)
# 當批次達到 BATCH_SIZE 時執(zhí)行批量插入
if len(batch) >= BATCH_SIZE:
sql = """
INSERT INTO students (name, age, gender, grade)
VALUES (%s, %s, %s, %s)
"""
cursor.executemany(sql, batch)
batch = [] # 清空批次
# 插入剩余的未滿批次的數(shù)據(jù)
if batch:
sql = """
INSERT INTO students (name, age, gender, grade)
VALUES (%s, %s, %s, %s)
"""
cursor.executemany(sql, batch)
# 提交事務
connection.commit()
except Exception as e:
print(f"插入數(shù)據(jù)時出現(xiàn)錯誤: {e}")
connection.rollback()
finally:
# 關閉數(shù)據(jù)庫連接
connection.close()4. 代碼詳解
- 生成隨機數(shù)據(jù):使用
generate_random_students函數(shù)生成 1 萬條隨機學生數(shù)據(jù),并存儲在students_data列表中。 - 數(shù)據(jù)庫連接:使用
PyMySQL連接到 MySQL 數(shù)據(jù)庫,并禁用自動提交模式,以便手動管理事務。 - 批量插入:
- 將數(shù)據(jù)分成大小為
BATCH_SIZE的批次進行插入操作。 - 使用
cursor.executemany方法批量插入每個批次的數(shù)據(jù),這樣可以減少 SQL 執(zhí)行次數(shù),提高效率。
- 將數(shù)據(jù)分成大小為
- 處理剩余數(shù)據(jù):如果數(shù)據(jù)量不足一個批次,最后將剩余數(shù)據(jù)插入。
- 事務管理:在插入成功后調(diào)用
connection.commit()提交事務,如果發(fā)生錯誤則進行回滾。 - 關閉連接:無論操作是否成功,都需要關閉數(shù)據(jù)庫連接。
四、性能優(yōu)化建議
- 調(diào)整批次大小:可以根據(jù)具體的硬件和數(shù)據(jù)量情況,適當調(diào)整批次大?。?code>BATCH_SIZE),通常 500 到 1000 條為一個批次較為合適。
- 禁用自動提交:將自動提交模式禁用(
connection.autocommit(False)),可以提高插入效率。 - 刪除或禁用索引:在大量數(shù)據(jù)插入時,可以暫時禁用或刪除表上的索引,插入完成后再重新建立索引。
- 批量插入語句優(yōu)化:可以將
INSERT INTO語句改為INSERT IGNORE或INSERT ON DUPLICATE KEY UPDATE來處理主鍵沖突的情況。 - unique: 盡量少用unique。當表的數(shù)據(jù)量很大時,每插入一個數(shù)據(jù)都會判斷該值是否唯一,會導致數(shù)據(jù)插入數(shù)據(jù)越來越慢。
五、總結(jié)
批量插入是提高 MySQL 數(shù)據(jù)插入性能的重要手段。通過使用批量插入技術,可以顯著減少 SQL 執(zhí)行次數(shù),提高數(shù)據(jù)導入的效率。本文通過一個學生信息表的實戰(zhàn)示例,詳細介紹了批量插入的實現(xiàn)方法,并提供了性能優(yōu)化的建議。希望這篇文章對您在處理大規(guī)模數(shù)據(jù)時有所幫助。
如果有更復雜的數(shù)據(jù)處理需求,您還可以考慮使用 MySQL 的 LOAD DATA 語句或?qū)iT的 ETL 工具來進行數(shù)據(jù)導入操作。
到此這篇關于MySQL 批量插入的原理和實戰(zhàn)方法(快速提升大數(shù)據(jù)導入效率)的文章就介紹到這了,更多相關mysql批量插入內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
詳解mysql8.0創(chuàng)建用戶授予權(quán)限報錯解決方法
這篇文章主要介紹了詳解mysql8.0創(chuàng)建用戶授予權(quán)限報錯解決方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-09-09
MySQL數(shù)據(jù)庫開發(fā)的36條原則(小結(jié))
這篇文章主要介紹了MySQL數(shù)據(jù)庫開發(fā)的36條原則(小結(jié)),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-09-09
MySQL數(shù)據(jù)庫學習之分組函數(shù)詳解
這篇文章主要為大家詳細介紹一下MySQL數(shù)據(jù)庫中分組函數(shù)的使用,文中的示例代碼講解詳細,對我們學習MySQL有一定幫助,需要的可以參考一下2022-07-07
一文詳解MySQL數(shù)據(jù)庫索引優(yōu)化的過程
在MySQL數(shù)據(jù)庫中,索引是一種關鍵的組件,它可以大大提高查詢的效率,但是,當數(shù)據(jù)量增大或者查詢復雜度增加時,索引的選擇和優(yōu)化變得至關重要,本文將記錄MySQL數(shù)據(jù)庫索引優(yōu)化的過程,以幫助開發(fā)人員更好地理解和應用索引優(yōu)化技巧2023-06-06
MySQL數(shù)據(jù)庫查詢性能優(yōu)化策略
這篇文章主要介紹了MySQL數(shù)據(jù)庫查詢性能優(yōu)化的策略,幫助大家的工作學習提高MySQL數(shù)據(jù)庫的性能,感興趣的朋友可以了解下2020-08-08
一文帶你了解MySQL之InnoDB統(tǒng)計數(shù)據(jù)是如何收集的
通過show index可以看到關于索引的統(tǒng)計數(shù)據(jù),那么這些統(tǒng)計數(shù)據(jù)是怎么來的呢,它們是以什么方式收集的呢,本章將聚焦于InnoDB存儲引擎的統(tǒng)計數(shù)據(jù)收集策略,需要的朋友可以參考下2023-05-05
MySQL中使用CTE獲取時間段數(shù)據(jù)的技巧分享
在數(shù)據(jù)庫操作中,獲取特定時間段的數(shù)據(jù)是一項常見任務,MySQL自從8.0版本開始支持CTE(公共表表達式),使得我們可以更加靈活和高效地處理時間段數(shù)據(jù),本文小編介紹了MySQL中使用CTE獲取時間段數(shù)據(jù)的技巧分享,需要的朋友可以參考下2024-08-08

