MySQL에서 데이터를 외부 파일로 직접 내보내고 싶은 경우가 있다. 예를 들어 대량의 데이터를 CSV 파일로 저장하거나, 특정 결과를 보고서 형태로 추출하고 싶을 때, SELECT INTO OUTFILE 구문은 매우 유용하다.
이 문법은 SELECT 쿼리 결과를 서버 파일 시스템에 직접 저장해주며, 복잡한 데이터 덤프 없이 간단히 파일을 생성할 수 있는 효율적인 방법이다.

✅ SELECT INTO OUTFILE 기본 문법
SELECT column1, column2
FROM table_name
INTO OUTFILE '/var/lib/mysql-files/output.csv'
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\n';
위 예제는 테이블에서 조회한 결과를 CSV 형식으로 저장하는 기본 구조이다.
- INTO OUTFILE 뒤에는 절대경로를 지정해야 하며, MySQL 서버가 해당 디렉토리에 쓰기 권한을 가지고 있어야 한다.
- FIELDS TERMINATED BY ',': 컬럼 구분자 설정 (CSV 구분자)
- ENCLOSED BY '"': 문자열을 큰따옴표로 감쌈
- LINES TERMINATED BY '\n': 줄바꿈 방식 지정
✅ INTO OUTFILE 주요 옵션 정리
| 옵션 | 설명 |
| FIELDS TERMINATED BY | 필드 간 구분자 지정 |
| ENCLOSED BY | 필드를 특정 문자로 감쌈 |
| ESCAPED BY | 특수 문자 이스케이프 설정 |
| LINES TERMINATED BY | 각 행의 끝 구분 방식 지정 |
이 옵션들을 적절히 조합하면 CSV뿐 아니라 TSV, Pipe-separated 형식 등 다양한 형태로 데이터를 저장할 수 있다.
예: 탭 구분 파일
SELECT * FROM employees
INTO OUTFILE '/var/lib/mysql-files/employees.tsv'
FIELDS TERMINATED BY '\t'
LINES TERMINATED BY '\n';
예: 파이프(|) 구분자 파일
SELECT * FROM products
INTO OUTFILE '/var/lib/mysql-files/products.txt'
FIELDS TERMINATED BY '|'
LINES TERMINATED BY '\r\n';
✅ 실전 예제: 지난 30일간 주문 데이터 저장
SELECT order_id, user_id, total_amount, order_date
FROM orders
WHERE order_date >= CURDATE() - INTERVAL 30 DAY
INTO OUTFILE '/var/lib/mysql-files/orders_last_30_days.csv'
FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n';
이 쿼리는 최근 한 달 동안의 주문 데이터를 CSV 파일로 내보낸다.
파일은 MySQL 서버가 접근할 수 있는 디렉토리에 저장되어야 하며, 로컬 PC가 아닌 서버의 파일 시스템에 위치하게 된다.
✅ 에러 발생 시 확인할 점
SELECT INTO OUTFILE을 사용할 때 다음과 같은 오류가 자주 발생한다.
1. 파일이 이미 존재한다
ERROR 1086 (HY000): File 'output.csv' already exists
MySQL은 보안을 위해 이미 존재하는 파일에 덮어쓰기를 허용하지 않는다. → 다른 파일명을 사용하거나 삭제 후 재시도해야 한다.
2. 디렉토리에 쓰기 권한 없음
- MySQL 서버가 해당 경로에 파일을 쓸 수 있는 권한이 있어야 한다.
- 일반적으로는 /var/lib/mysql-files/를 사용하는 것이 안전하다.
- Ubuntu, CentOS 기준으로 secure_file_priv 시스템 변수로 경로가 제한될 수 있다.
SHOW VARIABLES LIKE 'secure_file_priv';
✅ 파일 다운로드는 어떻게 하나?
SELECT INTO OUTFILE은 서버에 파일을 저장하기 때문에, 이를 로컬 PC로 가져오려면 SFTP, SCP, 또는 웹 UI를 통해 다운로드해야 한다.
phpMyAdmin이나 MySQL Workbench에서는 INTO OUTFILE 대신 Export 기능을 활용하면 더 편리하다.
✅ 보안 주의사항
- 서버에 민감한 데이터를 직접 노출하는 경로를 사용하면 안 된다.
- 반드시 접근이 통제된 디렉토리에 저장해야 하며, 저장 후에는 필요 시 삭제하는 것이 좋다.
- 외부 접속 허용된 서버에서는 secure_file_priv 경로 제한이 활성화되어 있는지 확인해야 한다.
✅ SELECT INTO OUTFILE vs mysqldump
| 기능 비교 | SELECT INTO OUTFILE | mysqldump |
| 목적 | SELECT 결과만 저장 | 전체 테이블 구조 + 데이터 백업 |
| 포맷 | CSV, TSV, 커스텀 형식 가능 | SQL 스크립트 |
| 대상 | 조회 결과 제한 가능 | 전체 테이블 단위 |
| 유연성 | 높음 | 낮음 |
보고서 생성, CSV 추출 목적이라면 INTO OUTFILE이 더 적합하다.
✅ 공식 문서 링크
- MySQL INTO OUTFILE 문서
https://dev.mysql.com/doc/refman/8.0/en/select-into.html - secure_file_priv 설명
https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_secure_file_priv
'DB' 카테고리의 다른 글
| [MySQL] UPDATE + WHERE (안전하고 정확한 데이터 수정 가이드) (0) | 2025.06.30 |
|---|---|
| [MySQL] UPDATE로 다중 컬럼 동시에 수정하는 방법 완벽 정리 (0) | 2025.06.30 |
| [MySQL] UPDATE 기본 문법 완벽 정리 – 데이터 수정 (3) | 2025.06.30 |
| [MySQL] SELECT INTO OUTFILE + LOAD DATA INFILE 완벽 가이드 – 쿼리 결과 파일로 저장하고 다시 불러오는 방법 (0) | 2025.06.30 |
| [MySQL] UNION과 UNION ALL 완전정복 – 다중 SELECT 결과 통합의 모든 것 (0) | 2025.06.30 |
| [MySQL] ENUM 성능 최적화와 실무 활용 팁 총정리 (0) | 2025.06.30 |
| [MySQL] SELECT와 ENUM 컬럼을 활용한 데이터 정합성 및 조회 최적화 전략 (1) | 2025.06.30 |
| [MySQL] SELECT 쿼리를 VIEW로 추상화 (복잡한 SQL을 깔끔하게 관리) (1) | 2025.06.30 |