# アウトオブコア処理 ## 定義 アウトオブコア処理(out-of-core processing)とは、中間データ構造(ハッシュテーブル・ソートバッファ等)や処理対象データがホストRAMの容量を超える場合に、その一部を一時的にディスクへ退避し、必要になった時点で再ロードすることでクエリ処理を継続する手法である。DB業界では退避動作を「スピリング(spilling)」、退避先から使わなくなったページを追い出し候補としてLRUキューに入れる動作を「アンピン(unpin)」、実際に追い出す動作を「エビクション(eviction)」と呼ぶ(Source: [[@2026__DiDi__Managing Memory + Grouped Aggregation]])。 [[DuckDB]]は既定でホストRAMの80%をクエリ処理に使用し(`memory_limit`パラメータで上限制御。PostgreSQLの`shared_buffers`既定値128MBとの対比が示される)、可能な限りメモリ上で処理しつつ、メモリが逼迫すると段階的にディスクベース処理へ移行する設計を採る(p.03)。スピリングが必要になりやすい典型的な演算は、グループ数の多いGROUP BY(ハッシュテーブル)、`count(DISTINCT)`、両テーブルがメモリを超えるJOIN、`ORDER BY`、sweeping frameを持つウィンドウ関数である(p.05)。 DuckDBはメモリ管理を、非ページ割り当て(ポインタベースの小さく断片化したデータ)・ページ割り当て(32KB〜256KBブロック単位、スピリング可能な中間データ)・ベーステーブルのバッファリング(`*.db`ファイルからの256KBブロック単位I/O、クエリが参照するカラムのみをバッファしLRUで追い出す)の3種に分け、単一のメモリ領域`memory_limit`で統合管理する(p.06-p.08)。可変長データを含むページ化中間データ構造(行指向レイアウト、German Strings)がスピル・再ロードされるとポインタが指す先のベースアドレスが変わりうるため、DuckDBはベースアドレスをData Pageの先頭にメタデータとして保存し、次回参照時に遅延的にポインタを付け替える(p.11)。 ## 横断的知見 - 今後の取り込みで、複数ソース間の関係を追記する。 ## 未解決の問い - ページ化中間データ構造のスピル先ディスクI/Oは同期・非同期のどちらで実装されているか。スピル先のディスク帯域が処理全体のボトルネックになる条件は何か。 - ベーステーブルのバッファリング(LRUキャッシュ)とスピリング(中間データの退避)は同一のページ管理機構を共有するが、両者が同時にメモリ逼迫を起こした場合の優先度(どちらを先に追い出すか)はどう決まるか。 - 他のOLAPエンジン(例: Umbra、Photon、Velox)のアウトオブコア処理はDuckDBの「ページ化中間データ+統一メモリ管理」設計とどう異なるか。今後の取り込みで比較する。 ## 関連 - ソース: [[@2026__DiDi__Managing Memory + Grouped Aggregation]] - 概念: [[ハッシュベースグループ集約]] - エンティティ: [[DuckDB]] / [[Torsten Grust]] / [[Universität Tübingen]] ## 出典 - [[@2026__DiDi__Managing Memory + Grouped Aggregation]](DuckDBのメモリ階層・統一メモリ管理・スピリング機構を解説する一次ソース)