"凌晨3点,老板突然甩来1个亿——别激动,是1亿条数据!要求天亮前入库且不影响线上业务,你慌不慌?"
在这里小编将手把手拆解Oracle、MySQL、PostgreSQL三大数据库的"暴力写入"黑科技,文末附全网独家的性能横评表,建议DBA速速收藏!
1.插入的担忧
事务风暴:频繁提交导致日志暴涨
索引泥潭:每次插入触发B+树重构
锁争用:行锁/表锁阻塞业务查询
硬件瓶颈:IOPS打满、内存爆仓
真实案例历历在目啊,某制造业工厂因批量导入引发15分钟服务中断,损失超白万!
2.Oracle篇
前置Buff叠满
-- 启用并行DML
ALTER SESSION ENABLE PARALLEL DML;
-- 调整redo日志组
ALTER DATABASE ADD LOGFILE GROUP 4 SIZE 2G;
hint核弹级组合
INSERT /*+ APPEND PARALLEL(users, 32) */ INTO users
SELECT * FROM external_table;
APPEND 直接路径插入绕过buffer cache PARALLEL 32 并行度根据CPU核数调整 NOLOGGING 非关键数据可禁用redo
监控TIP
SELECT * FROM v$session_longops
WHERE time_remaining > 0;
SQL*Loader Direct Path Load
sqlldr userid=scott/tiger control=load_data.ctl direct=true
外部表 + INSERT APPEND
CREATE TABLE ext_table (...) ORGANIZATION EXTERNAL (...);
INSERT /*+ APPEND */ INTO target_table SELECT * FROM ext_table;
DML锁机制
ALTER TABLE target_table NOLOGGING;
性能指标
- 单线程:约 50万行/秒
- 并行模式:可达 200万行/秒
3.MySQL篇
保命三板斧
使用percona-xtrabackup提前热备
SET autocommit=0;
SET unique_checks=0;
SET foreign_key_checks=0;
innodb_flush_log_at_trx_commit = 0
innodb_buffer_pool_size = 32G
bulk_insert_buffer_size = 256M
涡轮增压写入
LOAD DATA INFILE '/data/users.csv'
INTO TABLE users
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n';
分而治之战术
split -l 1000000 huge_file.csv
nohup mysqlimport --user=dba --threads=16 db_name parts* &
性能指标
- LOAD DATA:约 50万行/秒
4.PostgreSQL篇
参数调整
wal_level = minimal# 最小化WAL日志
fsync = off# 关闭强制刷盘
max_wal_size = 20GB
checkpoint_timeout = 1h
超级武器COPY
COPY users FROM '/data/users.csv'
WITH (FORMAT csv, HEADER, DELIMITER ',');
wal_level=minimal 关闭WAL日志
maintenance_work_mem=2GB 提升排序效率
并行插入黑魔法
CREATE TABLE users_new (LIKE users) PARTITION BY RANGE(id);
INSERT INTO users_new SELECT * FROM users_old;
事务优化:
每10万条手动提交
使用UNLOGGED表暂存中间数据
FDW联邦加速
CREATE EXTENSION file_fdw;
CREATE SERVER import_server FOREIGN DATA WRAPPER file_fdw;
CREATE FOREIGN TABLE temp_import (...) SERVER import_server;
性能指标
- COPY 命令:约 100万行/秒
- 并行插入:可达 300万行/秒
4.三大数据库性能对决
结语
"没有最好的方案,只有最合适的场景!你在实战中还用过哪些神仙操作?欢迎在留言区分享