쿼리 실행

쿼리 실행 (Run Queries, WebAssembly)

DuckDB-Wasm은 데이터를 쿼리하는 함수를 제공해요. 쿼리는 순차적으로 실행돼요:

  1. 먼저 connect를 호출해 연결을 만든다.
  2. 그다음 query를 호출해 전체 결과를 물리거나(materialize), send를 호출해 결과 청크를 지연 로드(lazily)한다.

이 페이지는 쿼리 실행, prepared statements, 결과를 JSON으로 변환, Parquet으로 내보내기를 다룬다.

출처: 문서

본문

쿼리 실행 (Query Execution)

전체 결과를 한 번에 원한다면 query()를, Apache Arrow record batch가 생성될 때마다 순회하려면 send()를 사용해요 — 큰 결과를 메모리에 전부 담기보다 스트리밍하고 싶을 때 유용해요:

// 새 연결 생성
const conn = await db.connect();

// 쿼리 결과를 물리거나
await conn.query<{ v: arrow.Int }>(`
    SELECT * FROM generate_series(1, 100) t(v)
`);
// ..., 또는 결과 청크를 지연 로드
for await (const batch of await conn.send<{ v: arrow.Int }>(`
    SELECT * FROM generate_series(1, 100) t(v)
`)) {
    // ...
}

// 메모리 해제를 위해 연결 닫기
await conn.close();

Prepared Statements

Prepared statements를 사용하면 쿼리를 한 번 파싱하고 서로 다른 파라미터 값으로 반복 실행할 수 있어요. 각 값은 ? 플레이스홀더 자리에 바인딩돼요. query()(물리화)와 send()(스트리밍) 모두 prepared statement에서 사용 가능해요:

// 새 연결 생성
const conn = await db.connect();
// 쿼리 준비
const stmt = await conn.prepare(`SELECT v + ? FROM generate_series(0, 10_000) t(v);`);
// ... 물리화된 결과로 실행
await stmt.query(234);
// ... 또는 결과 청크로
for await (const batch of await stmt.send(234)) {
    // ...
}
// 메모리 해제를 위해 statement 닫기
await stmt.close();
// 연결을 닫으면 statement도 해제됨
await conn.close();

Arrow 테이블을 JSON으로

쿼리 결과는 Arrow 테이블로 반환돼요. 결과를 일반 JavaScript 객체로 변환하려면 테이블의 행을 매핑하고 각각에 toJSON()을 호출해요:

// 새 연결 생성
const conn = await db.connect();

// 데이터 쿼리
const arrowResult = await conn.query<{ v: arrow.Int }>(`
    SELECT * FROM generate_series(1, 100) t(v)
`);

// Arrow 테이블을 JSON 객체 배열로 변환
const result = arrowResult.toArray().map((row) => row.toJSON());

// 메모리 해제를 위해 연결 닫기
await conn.close();

Parquet으로 내보내기

쿼리 결과를 내보내려면 COPY로 가상 파일 시스템의 Parquet 파일에 쓰고, 그 파일의 바이트를 다운로드하거나 처리할 수 있는 버퍼로 복사해요:

// 새 연결 생성
const conn = await db.connect();

// 쿼리 결과를 가상 파일 시스템의 Parquet 파일로 내보내기
await conn.query(`COPY (SELECT * FROM tbl) TO 'result-snappy.parquet' (FORMAT parquet);`);

// 파일 내용을 버퍼로 복사
const parquetBuffer = await db.copyFileToBuffer('result-snappy.parquet');

// 다운로드 링크 생성
const link = URL.createObjectURL(new Blob([parquetBuffer]));

// 메모리 해제를 위해 연결 닫기
await conn.close();

더 알아보기 (Learn more)

  • [Import Data]({% link docs/current/clients/wasm/data_ingestion.md %}) — 이 쿼리들이 읽는 데이터를 로드하는 방법.
  • [Load Extensions]({% link docs/current/clients/wasm/extensions.md %}) — 내보내기 예시에서 사용하는 Parquet 확장과 기타 쿼리 시 확장.
  • [Prepared Statements]({% link docs/current/sql/query_syntax/prepared_statements.md %}) — 여기서 보여준 파라미터화 쿼리에 대한 DuckDB의 SQL 수준 지원.
  • [Instantiate]({% link docs/current/clients/wasm/instantiation.md %}) — 연결이 열리는 db를 만들기.
  • [Troubleshoot]({% link docs/current/clients/wasm/troubleshoot.md %}) — 메모리 한도 내에 머물기 위해 send()로 결과를 스트리밍하기.