DBAtlas · 数据库运维图谱

批量加载数据(CSV / 从文件)

Oracle

-- SQL*Loader (from the shell)
sqlldr app_user/password control=customer.ctl log=load.log

-- Contents of customer.ctl:
-- LOAD DATA INFILE 'customer.csv'
-- INTO TABLE customer FIELDS TERMINATED BY ','
-- (id, name, email)

-- Alternative: with an external table
CREATE TABLE ext_customer (id NUMBER, name VARCHAR2(100))
ORGANIZATION EXTERNAL (TYPE ORACLE_LOADER DEFAULT DIRECTORY dir_csv
  ACCESS PARAMETERS (FIELDS TERMINATED BY ',') LOCATION ('customer.csv'));

最常用的工具是 SQL*Loader(配合控制文件)。若要像查询一样读取文件,使用外部表。大数据量时,直接路径加载(DIRECT=TRUE)速度很快。

PostgreSQL

-- Server side (file on the server; requires superuser/pg_read_server_files)
COPY customer (id, name, email) FROM '/data/customer.csv' WITH (FORMAT csv, HEADER true);

-- Client side (psql, file on the client)
\copy customer (id, name, email) FROM 'customer.csv' WITH (FORMAT csv, HEADER true)

COPY 读取服务器上的文件,需要相应权限;psql \copy 读取客户端文件,无需额外权限。这是加载 CSV 最快的方式。

MySQL

-- Server side
LOAD DATA INFILE '/data/customer.csv' INTO TABLE customer
FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 LINES;

-- From a client file
LOAD DATA LOCAL INFILE 'customer.csv' INTO TABLE customer
FIELDS TERMINATED BY ',' IGNORE 1 LINES;

LOAD DATA INFILE 是最快的批量加载方式。LOCAL 读取客户端文件,必须在服务器(local_infile=ON)和客户端两侧都启用。secure_file_priv 限制服务器路径。

SQL Server

-- T-SQL BULK INSERT
BULK INSERT customer FROM 'C:\data\customer.csv'
WITH (FORMAT='CSV', FIRSTROW=2, FIELDTERMINATOR=',', ROWTERMINATOR='0x0a');

-- bcp from the shell
bcp mydb.dbo.customer in customer.csv -c -t, -S server -T

BULK INSERT 从 SQL Server 服务账户可访问的路径读取文件。bcp 是命令行工具;-c 为字符模式,-t 为字段分隔符。为获得最高速度,使用 TABLOCK 争取最小日志记录。

MongoDB

# Import CSV / JSON (from the shell)
mongoimport --db=shop --collection=customer --type=csv --headerline --file=customer.csv

# For a JSON array
mongoimport --db=shop --collection=customer --file=customer.json --jsonArray

mongoimport 加载 CSV/TSV/JSON;--headerline 将第一行视为字段名。更新现有文档使用 --mode=upsert --upsertFields。大数据量时 --numInsertionWorkers 可加快速度。

Redis

# Fastest: feed commands in protocol format and pipe them
cat commands.txt | redis-cli --pipe

# Example lines in commands.txt:
# SET customer:1 "Alice"
# SET customer:2 "Bob"

批量加载使用 redis-cli --pipe(mass insert);它通过单个连接以 RESP 协议格式流式发送命令,因此速度非常快。也可以通过 pipelining 对命令分组。

Elasticsearch

# _bulk API (NDJSON: an action line + a source line per document)
curl -s -H 'Content-Type: application/x-ndjson' -XPOST 'localhost:9200/customer/_bulk' --data-binary @data.ndjson

# Contents of data.ndjson:
# { "index": {} }
# { "id": 1, "name": "Alice" }
# { "index": {} }
# { "id": 2, "name": "Bob" }

_bulk API 接收 NDJSON(每个文档一行操作 + 一行数据;文件必须以 \n 结尾)。CSV 使用 Logstash、Filebeat 或 elasticdump。加载期间禁用 refresh_interval 可加快速度。

在 DBAtlas 中打开 →