데이터 대량 적재(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(컨트롤 파일 사용)다. 파일을 쿼리처럼 읽으려면 external table을 사용한다. 대용량에는 direct path load(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 -TBULK 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 --jsonArraymongoimport는 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을 받는다(문서마다 action 줄 + data 줄, 파일은 \n으로 끝나야 함). CSV는 Logstash, Filebeat 또는 elasticdump를 사용한다. 적재 중 refresh_interval을 비활성화하면 속도가 빨라진다.