# SQLite가 Bytecode를 사용하는 이유

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

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=14584](https://news.hada.io/topic?id=14584)
- GeekNews Markdown: [https://news.hada.io/topic/14584.md](https://news.hada.io/topic/14584.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2024-05-01T09:45:07+09:00
- Updated: 2024-05-01T09:45:07+09:00
- Original source: [sqlite.org](https://sqlite.org/draft/whybytecode.html)
- Points: 7
- Comments: 1

## Topic Body

### SQL 데이터베이스 엔진의 일반적인 작동 방식  
- 모든 SQL 데이터베이스 엔진은 비슷한 방식으로 동작함  
  - 입력된 SQL 문을 "준비된 문장(Prepared Statement)"으로 변환  
  - 준비된 문장을 "실행"해서 결과를 생성  
- SQLite에서 준비된 문장은 sqlite3_stmt 객체의 인스턴스로 표현됨  
- 준비된 문장을 표현하는 방법은 크게 두 가지  
  - 바이트코드 방식: SQLite에서 사용  
  - 객체 트리 방식: MySQL, PostgreSQL에서 사용   
  
### 바이트코드 방식의 장점  
- 이해하기 쉬움   
  - 단순한 명령어들의 나열로 구성되어 쉽게 출력 가능  
  - EXPLAIN 키워드를 사용하면 SQL 문장의 바이트코드 확인 가능  
- 디버깅이 용이함  
  - 파싱/분석 단계와 실행 단계를 명확히 구분  
  - 디버깅 빌드에서 PRAGMA vdbe_trace=ON 명령으로 바이트코드 실행 추적 가능  
- 증분식으로 실행 가능  
  - 바이트코드로 작성된 SQL 문은 한 행씩 실행하고 중지했다 재개 가능  
  - 객체 트리 방식은 전체 트리를 한번에 실행하므로 증분 실행이 어려움  
- 메모리 사용량이 적음  
  - 바이트코드는 AST보다 크기가 작음  
  - Prepared Statement는 오래 메모리에 캐싱되므로 메모리 사용량이 중요  
- 실행 속도가 빠름  
  - 각 단계에서 결정해야 할 사항이 적어 실행이 빠름  
  
### 객체 트리 방식의 장점  
- 런타임에 쿼리 계획을 수정할 수 있음  
  - 객체 트리는 실행 중에도 수정이 용이함  
  - 쿼리의 진행 상황에 따라 동적으로 최적화 가능  
- 병렬화하기 쉬움  
  - 각 처리 노드를 별도 스레드에 할당 가능  
  - 노드 간 데이터 전달만 동기화하면 됨  
  - 대용량 분석 쿼리(OLAP)를 다중 코어에서 실행할 때 유리  
  
### GN⁺의 의견  
- SQLite의 주요 목표는 사물인터넷 환경에서의 트랜잭션 처리(OLTP)이므로, 바이트코드 방식이 적합해 보임. 간단하고 가벼우면서도 빠른 성능을 제공할 수 있기 때문임.  
- 반면 MySQL이나 PostgreSQL은 대용량 데이터 분석에도 많이 사용되므로, 쿼리 실행 계획을 동적으로 최적화하고 병렬화할 수 있는 객체 트리 방식의 장점이 더 부각될 수 있음.  
- 다만 객체 트리 방식도 디버깅이나 성능 분석이 어렵다는 단점이 있음. 또한 트리 순회 비용 등으로 인해 간단한 쿼리의 경우 오히려 바이트코드보다 느릴 가능성도 있음.  
- 중요한 점은 용도와 목적에 맞는 적절한 방식을 선택하는 것. 범용 RDBMS의 경우 두 방식의 장단점을 절충한 하이브리드 방식을 사용하는 것도 고려해볼 만함.

## Comments



### Comment 24827

- Author: neo
- Created: 2024-05-01T09:45:07+09:00
- Points: 2

###### [Hacker News 의견](https://news.ycombinator.com/item?id=40206752)   
- SQLite가 SQL 쿼리 실행을 위해 추상 구문 트리(AST) 대신 바이트코드 가상 머신(VM)을 사용하는 것은 데이터베이스에 있어 흥미로운 설계 선택임. 바이트코드가 AST보다 갖는 장점은 다음과 같음:  
  - **컴팩트함**: 바이트코드는 하위 표현식에 대한 숨겨진 malloc/객체 헤더와 포인터가 필요하지 않아 AST보다 더 컴팩트함.  
  - **성능**: 캐시 활용도가 높고 포인터 추적으로 인한 캐시 미스가 적어 바이트코드 실행이 더 빠름.  
  - **증분 실행**: 명시적 스택을 사용하여 기본 스택을 풀지 않고도 실행을 일시 중지하고 재개하는 것이 바이트코드로 더 쉬움.  
  
- 바이트코드 VM과 인터프리터는 종종 범용 프로그래밍 언어와 연관되지만, 다음과 같은 다른 맥락에서도 놀랍도록 유용할 수 있음:  
  - **eBPF**: Linux 커널의 확장 메커니즘.  
  - **DWARF 표현 언어**: GDB, LLDB 같은 디버거에서 사용됨.  
  - **RAR 파일 포맷**: 사용자 정의 데이터 변환을 위한 바이트코드 인코딩을 포함함.  
  
- Microsoft SQL Server는 내부적으로 객체 트리를 사용하지만, 쿼리 플랜 출력은 여전히 테이블 형태로, 객체 트리를 테이블로 렌더링하는 것이 어려움을 보여줌.  
  
- 프로그래머는 종종 어떤 인덱스 조회가 루프에서 일어나야 하는지 정확히 알고 있으므로, 경우에 따라 SQL 대신 바이트코드를 직접 작성하거나 고수준의 명령형 언어를 사용하는 것이 유리할 수 있음. SQL로 이를 표현하는 것은 부담이 될 수 있음.  
  
- 병목현상이 바이트코드 실행에 있지 않다면(예: 메모리나 디스크 속도), JIT 컴파일을 통해 네이티브 코드로 변환하는 것이 꼭 필요하지 않을 수 있음.   
  
- Python, Ruby, Lua 등 많은 프로그래밍 언어가 내부적으로 바이트코드나 AST를 사용함. 데이터베이스 설계 결정으로 인해 오류가 발생하기 쉬운 서드파티 라이브러리나 ORM 구현에 쉽게 파싱 가능한 명령문이 유용할 수 있음.
