# SQLite: 파일 시스템보다 35% 더 빠름

> Clean Markdown view of GeekNews topic #16044. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=16044](https://news.hada.io/topic?id=16044)
- GeekNews Markdown: [https://news.hada.io/topic/16044.md](https://news.hada.io/topic/16044.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2024-07-28T09:47:34+09:00
- Updated: 2024-07-28T09:47:34+09:00
- Original source: [sqlite.org](https://sqlite.org/fasterthanfs.html)
- Points: 15
- Comments: 4

## Summary

SQLite는 작은 Blob을 개별 파일보다 35% 더 빠르게 읽고 쓰며, 디스크 공간도 약 20% 적게 사용합니다. 이는 open()과 close() 시스템 호출의 오버헤드가 줄어들기 때문이며, 특히 안티바이러스 소프트웨어가 활성화된 Windows 시스템에서 더욱 두드러집니다. SQLite는 데이터베이스 파일 하나만 변경하므로 대량의 작은 파일을 다루는 애플리케이션에서 성능 향상에 유리합니다.

## Topic Body

- SQLite는 작은 Blob(예: 썸네일 이미지)를 개별 파일에서 fread()나 fwrite()로 읽거나 쓰는 것보다 35% 더 빠르게 읽고 쓸 수 있음  
- 또한 10KB Blob을 저장하는 단일 SQLite 데이터베이스는 개별 파일로 Blob을 저장하는 것보다 디스크 공간을 약 20% 적게 사용함  
- 성능 차이는 SQLite 데이터베이스에서 작업할 때 open()과 close() 시스템 호출이 한 번만 호출되는 반면, 개별 파일의 Blob을 사용할 때는 각 Blob마다 open()과 close()가 한 번씩 호출되기 때문에 발생하는 것으로 보임. open()과 close()의 오버헤드가 데이터베이스 사용 오버헤드보다 큰 것으로 보임  
- 크기 감소는 개별 파일이 파일 시스템 블록 크기의 다음 배수로 채워지는 반면, Blob은 SQLite 데이터베이스에 더 조밀하게 포장되기 때문에 발생함  
  
### 주의사항  
- 35%라는 수치는 대략적인 것임. 실제 타이밍은 하드웨어, 운영 체제, 실험 세부 사항에 따라 다르며 실제 하드웨어에서 무작위 성능 변동이 있음  
- 35%라는 수치는 저자가 쉽게 사용할 수 있는 모든 시스템에서 테스트를 실행한 결과임. 일부 리뷰어들은 그들의 시스템에서 SQLite가 직접 I/O보다 더 높은 지연 시간을 가진다고 보고함. 아직 그 차이를 이해하지 못함  
- SQLite는 차가운 파일 시스템 캐시를 사용하여 실험을 실행할 때 직접 I/O만큼 잘 수행되지 않는 것으로 나타남  
- 이 문서는 관계형 데이터베이스가 직접적인 파일 시스템 I/O보다 느려야 한다는 일반적인 가정을 반박함  
- 2022년 연구에 따르면 실제 작업에서 SQLite는 Linux의 Btrfs 및 Ext4에 비해 대략 2배 더 빠른 것으로 나타남  
  
### 측정 방법  
- I/O 성능은 SQLite 소스 트리의 kvtest.c 프로그램을 사용하여 측정됨  
- 이 테스트 프로그램을 컴파일하려면, SQLite 아말감 소스 파일 "sqlite3.c"와 "sqlite3.h"와 함께 kvtest.c 소스 파일을 디렉터리로 수집한 다음, Unix에서 다음과 유사한 명령을 실행함  
- 이 명령의 결과로 나오는 "kvtest" 프로그램을 사용하여 100,000개의 무작위 비압축 Blob으로 구성된 테스트 데이터베이스를 생성하며, 각 Blob의 크기는 8,000바이트에서 12,000바이트 사이임  
- 모든 Blob의 사본을 디렉터리의 개별 파일로 만들기 위해 --tree 명령줄 옵션을 사용하여 "export" 명령을 실행할 수 있음  
- 데이터베이스에서 Blob을 읽고 개별 파일에서 Blob을 읽는 성능을 측정하기 위해 다음 명령을 사용함  
- --blob-api 옵션을 사용하면 SQLite가 SQL 문을 실행하는 대신 sqlite3_blob_read() 기능을 사용하여 Blob 내용을 로드할 수 있어 읽기 테스트에서 조금 더 빠르게 실행됨  
  
### 읽기 성능 측정  
- Windows10에서는 SQLite 데이터베이스에서 콘텐츠를 디스크에서 직접 읽는 것보다 약 5배 더 빨리 읽을 수 있음  
- Android에서는 SQLite가 디스크에서 읽는 것보다 약 35% 더 빠름  
- 메모리 매핑된 데이터베이스에서 sqlite3_blob_read()를 사용하여 읽을 때 Mac과 Android에서는 디스크에서 개별 파일을 읽는 것보다 2배 더 빠르고 Windows에서는 10배 더 빠름  
  
### 쓰기 성능 측정  
- 모든 시스템에서 직접 I/O와 SQLite 모두 쓰기 성능이 읽기보다 5~15배 느림  
- 쓰기 테스트에서 안티바이러스 소프트웨어는 SQLite 쓰기에는 거의 영향을 미치지 않지만 직접 디스크에 쓰기는 10배 정도 느려짐  
- 이는 아마도 SQLite는 단일 데이터베이스 파일만 변경하는 반면 직접 디스크에 변경하는 것은 안티바이러스에서 검사해야 하는 수천 개의 개별 파일을 변경하기 때문일 것임  
  
### 일반적인 결과  
- SQLite는 읽기와 쓰기 모두에서 별도의 디스크 파일에 저장된 Blob과 경쟁력이 있으며 대개 더 빠름   
- SQLite는 안티바이러스 보호 기능이 켜져 있을 때 Windows에서 디스크에 직접 쓰기보다 훨씬 더 빠름  
- 읽기는 모든 시스템에서 그리고 SQLite와 직접 디스크 I/O 모두에서 쓰기보다 약 10배 더 빠름  
- I/O 성능은 운영 체제와 하드웨어에 따라 크게 다름. 결론을 내리기 전에 자체 측정이 필요함  
- 일부 다른 SQL 데이터베이스 엔진은 개발자에게 Blob을 별도의 파일에 저장한 다음 데이터베이스에 파일 이름을 저장할 것을 조언함. 이 경우 전체 Blob을 데이터베이스에 저장하면 SQLite에서 훨씬 더 빠른 읽기 및 쓰기 성능을 제공함  
  
### GN⁺의 의견  
- SQLite의 성능이 개별 파일을 읽고 쓰는 것보다 우수하다는 점이 매우 흥미로움. 이는 데이터베이스를 사용하는 애플리케이션의 성능 향상에 도움이 될 것으로 보임  
- 그러나 이 벤치마크 결과가 모든 상황에 일반적으로 적용되는 것은 아님. 데이터의 특성, 액세스 패턴, 하드웨어 구성 등에 따라 달라질 수 있음. 중요한 애플리케이션의 경우 실제 작업 부하를 사용하여 벤치마크를 수행하는 것이 중요함   
- 또한 SQLite는 안티바이러스 검사를 피할 수 있다는 장점이 있음. 이는 대량의 작은 파일을 다루는 애플리케이션에서 특히 유용할 것임  
- SQLite의 단점은 모든 데이터가 단일 파일에 저장되기 때문에 데이터베이스 파일이 손상되면 모든 데이터가 손실될 수 있다는 점임. 따라서 데이터베이스 파일을 정기적으로 백업하는 것이 중요함

## Comments



### Comment 27629

- Author: iolothebard
- Created: 2024-07-28T23:20:20+09:00
- Points: 2

데이터베이스에 파일 속성(파일 이름, 크기, 접근 권한, …)에 대한 접근까지 포함하던가,  
그게 아니라면 파일 입출력이 아니라 블럭 입출력과 비교해야하는데 아닐까 싶은데요…  
이랬던 저랬던 SQLite가 빠르긴 하죠.

### Comment 27606

- Author: neo
- Created: 2024-07-28T09:47:34+09:00
- Points: 2

###### [Hacker News 의견](https://news.ycombinator.com/item?id=41085376) 
- 파일 시스템 속성이나 메타데이터가 없어서 추가적인 속성 기록이나 업데이트가 필요 없고, 물리 파일이나 파이프/심볼릭 링크 확인, 권한 검사, 블록 크기 정렬 불일치 등이 없어서 단일 오픈 명령어만 필요함
  - 기능을 버리고 범용 설계를 무시할 때 이해할 수 있는 부분임
  - SQLite에 대한 fuse 매핑을 사용하고 디렉토리를 마운트하여 접근하면 성능이 비슷하거나 더 느릴 수 있음
  - 속성을 비활성화하고 최적화된 블록 크기로 커스텀 파일 시스템을 만들면 비슷한 성능을 얻을 수 있음
  - rsync 같은 쉘 명령어를 사용하여 파일을 탐색하고 조작할 수 있는 단순함이 있음
  - SQLite는 패키지된 정적 자산이나 어플라이언스 타입 애플리케이션에 적합함

- Windows 10에서 4배 속도 증가가 Windows 파일 시스템 호출이 얼마나 느린지 강조함

- 디지털 피아노에서 나오는 모든 노트를 실시간으로 기록하는 아이디어를 가짐
  - SQLite를 사용하여 각 행이 피아노의 MIDI 이벤트인 단일 테이블로 저장함
  - 성능이 좋고 나중에 분석할 수 있음

- 데이터베이스 연구실에서 OS 연구와 비교하는 것이 흥미로웠음
  - 관계형 데이터베이스는 작은 개별 레코드와 일관성을 위해 최적화됨
  - 행 크기가 커질수록 성능이 급격히 떨어짐

- WAL2 모드에서 sqlite DB에 추가하는 것을 고려 중임
  - 쓰기 성능 페널티가 거의 없고 읽기/분석에 큰 장점이 있음

- SQLite 데이터베이스에서 open()과 close() 시스템 호출이 한 번만 호출됨
  - 개별 파일에서 블롭을 사용할 때보다 오버헤드가 적음

- SQLite 블롭 필드를 사용하여 파일을 저장하는 것은 권장하지 않음
  - 블롭 최대 크기가 2GB임
  - 객체를 바이트로 직렬화/역직렬화해야 함
  - 다른 시스템/서비스와 상호작용하려면 파일이 필요함
  - SQLite는 병렬 요청을 처리하는 설정이 있지만, 경쟁 요청으로 인해 데이터베이스가 잠김

- 파일 시스템 위에 구축된 것이 파일 시스템보다 빠르다는 것은 최적화되지 않은 방식으로 파일 시스템을 사용할 때 느리다는 의미임

- SQLite 데이터베이스에서 많은 행을 삭제하는 것이 파일을 삭제하는 것보다 느림

- 모든 파일 시스템/드라이브 접근은 OS에 의해 관리됨
  - 데이터베이스 파일이 디스크에 클러스터로 저장됨
  - 데이터베이스 관리 시스템은 특정 도메인과 문제를 해결하기 위해 편리하게 만들어짐

### Comment 27623

- Author: halfenif
- Created: 2024-07-28T13:59:26+09:00
- Points: 2
- Parent comment: 27606
- Depth: 1

20년 전에 파일을 blob으로 oracle db에 넣는 아키텍처를 잘 사용했으나.. 매번 사람들에게 그 장점을 설명해야 했음. 물론 매번 성공적이지는 않았음.

### Comment 27645

- Author: narusas
- Created: 2024-07-29T10:09:11+09:00
- Points: 1
- Parent comment: 27623
- Depth: 2

20년 전이면 오라클 SAN DISK 가격이 만만치 않았을텐데요..
