PostgreSQL の B-Tree インデックスを理解する:包括的ガイド~パート 1~

2026/07/06 4:55

PostgreSQL の B-Tree インデックスを理解する:包括的ガイド~パート 1~

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

PostgreSQL は、B 木、ハッシュ、GiST、SP-GiST、GIN、BRIN など多様なインデックスタイプを提供することで、高いパフォーマンスのクエリを実現します。それぞれは、異なるアクセスパターンとデータ分布に対応する専用のアルゴリズムで設計されています。検索効率の核となるのは B-木であり、これはすべてのリーフノードが同じレベルにあり、その上位に空の部分木が存在しないバランストな構造です。データはソート順(左が最小、右が最大)で保持され、標準的な B 木インデックスは挿入と檢索を効率的にサポートするために Lehman–Yao アルゴリズムを依存しています。ディスク上で B-木は有向グラフとして機能します:内部ノードは下方向に指し、リーフページは橋渡しポインタ (

btpo_prev
,
btpo_next
) によってリンクされ、ルートへ再三登降することなく前後の遍歴を可能にします。

インデックスのリーフは完全な行データを格納せず、代わりにキーと

ctid
を通じた行への参照のみ保持します。これは、格納ファイル内の物理ブロック番号とオフセットを符号化しており、インデックスを使用しない場合のようにすべてのエントリを上回る高価なシーケンシャルスキャンを行わずに特定の行を直接位置付けることを可能にします。各インデックスレコードは、対象とする範囲の上界を示す「high key」を含み、その後実際のインデックスされたデータ値(例:bigint)が続きます。

インデックスに加え、PostgreSQL はテーブルの格納を自動的に管理します:1 GB 未満のファイルは単一のオブジェクトとして残され、より大きなテーブルは複数の 1 GB セグメントに分割されます。各データページは、利用可能なスペース、トランザクションポインタ、タプルに関するメタデータを追跡するヘッダーを持っています。エンジニアは

pg_class
(オブジェクト OID、関係名、スキーマ、所有者、テーブルスペース、ページ数、タプル数、タイプ、ファイルパスを報告)のようなシステムビューや、
pageinspect
などの拡張機能を通じて、これらの内部構造に深く洞察を得ることができます。これらの拡張機能には、トポロジーとページ統計を分析するための
bt_metap
,
bt_page_stats
,
bt_page_items
といった関数が含まれます。これらアーキテクチャ上の特徴は、共に高精度なパフォーマンスチューニング、高速なクエリ実行、そして高ボリュームかつ複雑なデータ環境において削減された計算量を実現します。

本文

PostgreSQL バルックツリーインデックス:内部機構と実装

大規模なテーブル上のクエリ最適化、特にフィルタリング操作が低下する際の実装戦略について解説します。効果的なインデックス利用には、内部機構の理解が不可欠です。


目次

  • PostgreSQL のインデックスの種類
  • バルックツリー(B-Tree)の論理的スキーマ
  • データ格納方式とメタデータ復習
  • バルックツリーインデックスの論理的表現
  • インデックスの実装詳細(PageInspect を活用して)
  • 結論:構造からの学び

PostgreSQL のインデックスの種類

PostgreSQL は、異なるアルゴリズムに基づいた以下のインデックスを提供します。用途に合わせて適切に選択する必要があります。

  • B-Tree: バランストツリー(デフォルト)
  • Hash: 等値比較に適したハッシュテーブル
  • GiST: 空間データや全般的な検索木
  • SP-GiST: 二次的な階層検索木
  • GIN: 逆インデックス(テキスト検索など)
  • BRIN: ブロック範囲インデックス(大規模テーブル用)

バルックツリー(B-Tree)の論理的スキーマ

「B-Tree」は**バランスド・ツリー(平衡木)**を意味し、すべてのレベルでルートからの距離が一致した構造を持っています。

主な特性

  • ノードの柔軟性: ノードは通常 2 つ以上の子ノードを持ち、樹の順序 $M$ によって定義される範囲内で変動します。
  • 高さ管理: 検索操作の最適化のために、高さを常に $\log_M N$ に保ちます。
  • ソート順序: データはソート順に格納され、左側に最小値、右側に最大値が配置されます。
  • 一貫性と効率性: すべてのリーフノードが同一レベルにあり、リーフ上方には空の部分木が存在しません。

比較:インデックス有無の複素性

  • インデックスなし: デフォルトでシークウェントスキャンを実施。全データエントリを反復処理するため、読み込み量は多いですが検索が遅いです($O(N)$)。
  • インデックスあり: 情報取得が劇的に早くなります。

[復習] PostgreSQL のデータ格納方式

テーブルは順序付けされたデータとして期待されますが、実際にはページ内や異なる位置に分散して格納されています。

メタデータの確認

テーブル

t
を作成し、以下のクエリで物理情報を取得します。

SELECT 
    class.oid AS "OID",
    relname AS "Relation Name",
    schema.nspname AS "Schema",
    usr.rolname AS "Object Owner",
    coalesce(tblsp.spcname, 'pg_default') AS "Tablespace",
    relpages AS "Amount Pages",
    reltuples AS "Amount Tuples",
    reltoastrelid AS "TOAST table",
    CASE 
        WHEN relpersistence = 'p' THEN 'Permanent'
        WHEN relpersistence = 't' THEN 'Temporary'
        ELSE 'Unlogged' 
    END AS "Type",
    pg_relation_filepath(class.oid) AS "File Path",
    pg_size_pretty(pg_relation_size(class.oid)) AS "Relation Size" 
FROM pg_class class 
INNER JOIN pg_namespace schema ON schema.oid = class.relnamespace 
INNER JOIN pg_authid usr ON usr.oid = class.relowner 
LEFT JOIN pg_tablespace tblsp ON tblsp.oid = class.reltablespace
WHERE relname = 't';

メタデータ解説

  • OID: システムシーケンスに基づき割り当てられた一意の識別子。
  • デフォルトテーブルスペース:
    pg_default
  • スキーマ: デフォルトは
    public
  • 所有者: アクセスを管理する作成者
  • ページ・タプル: 物理的なページ数と記録(行)の数
  • TOAST テーブル: 長すぎるデータを分割して格納する補助テーブル
  • ファイルパス:
    pg_home
    ディレクトリ内のバイナリファイルパス

ファイル構造の特徴

  • 1GB 未満のテーブルは単一ファイルに格納されます。
  • 1GB を超える場合、データは最大 1GB の複数のファイルに分割されます。

ctid
とページの構造

  • CTID: テーブル内の各行の一意な物理的識別子(ブロック番号とオフセット)。
  • ページ構造: ヘッダー部を含み、下から上へと成長します。データ挿入時は左下から書き込まれ、ポインタ値を参照します。
  • バルックツリーインデックスのリーフノードは、特定のファイル内の特定の
    ctid
    を指しています。

バルックツリーインデックスの論理的表現

インデックスはテーブルデータファイルと隣接する独立したファイルとして存在します。作成命令は以下の通りです。

CREATE INDEX index_name ON table_name (column_name);

検索プロセス(例:値 37 の検索)

  1. ルートから開始: ルートノードと比較開始。
  2. 分岐:
    • $13 < 37$ なので、右へ移動。
    • ノードで $31 < 37 < 41$ と判断。
  3. リーフ到達: 第 3 レベルの対応するノードに進み、一致する行の住所(
    ctid
    )を発見。
  4. データ取得: 特定のページへ移動し、情報を取得します。フルテーブルスキャンを回避できます。

インデックスの実装詳細:PageInspect を活用して

インデックスの内部構造を確認するには、拡張機能

pageinspect
を使用します。PRIMARY KEY や UNIQUE 制約もデフォルトで B-Tree インデックスを作成します。

ステップ 1: 拡張と単純なデータ挿入

CREATE EXTENSION IF NOT EXISTS pageinspect;

-- テーブル作成
CREATE TABLE IF NOT EXISTS public.client ( id int, name varchar);
CREATE INDEX idx_client ON public.client (id);

-- データ挿入
INSERT INTO public.client VALUES (1, 'Row #1');

-- メタデータ確認
SELECT * FROM bt_metap('idx_client');
  • Fast Root: ページ番号
    1
    。木のトポロジーと検索方法を定義します。
  • bt_page_stats: 特定ページの統計情報(タイプ、アイテム数など)を取得します。
  • bt_page_items: ページ内の具体的な要素(
    ctid
    など)を返します。

この時点では、タイプは "L" (Leaf) であり、ルートも葉として機能しています。

ステップ 2: データ量増加に伴う構造変化

データを 1,000 件追加し、インデックスの再構築を確認します。

TRUNCATE TABLE public.client;
INSERT INTO public.client 
SELECT i, 'Row #'||i::VARCHAR  
FROM generate_series(1,1000) AS k(i);

SELECT * FROM bt_metap('idx_client');

構造変化の観察

  • タイプ: "Root" に変化します。
  • アイテム数: ルートノードには複数の子へのポインタ(例:2 つ目以降)が生成されます。
  • 範囲管理: ルートからはリーフへジャンプするブリッジ(ページ間リンク)が形成されます。
    • レーフ 1: 0 〜 366
    • レーフ 2: 367 〜 732
    • レーフ 3: 733 以降

ポインタと効率化の仕組み

  • ブリッジ: ページ間を結ぶポインタ(
    btpo_prev
    ,
    btpo_next
    )。
  • ハイキー: ページ内の最初のレコード。境界を示し、後続のデータから始まります。
  • 最適化のポイント: ルートを再訪問するのではなく、ポインタを辿って次の状態へ直接移動できるため検索が高速化します。

結論:構造からの学び

厳密に言えば、B-Tree は「木」ではなく、リーフ同士が相互接続された有向グラフです。

  • ブリッジ(ページ間リンク): オプティマイザが次にどこに進むべきかを理解させます。
  • 効率性の向上: ルートを介して全ページを再訪問するのではなく、ポインタを経由して素早くターゲットに到達できます。
  • 原子単位での管理: ページはテーブルとインデックスの両方で原子として機能し、統一された構造がストレージニーズをサポートしています。

この内部機構を理解することで、より効率的なクエリプランニングやシステム設計が可能になります。

同じ日のほかのニュース

一覧に戻る →

2026/07/09 5:05

FAANGシミュレーター

## Japanese Translation: 「FAANG™ Life Simulator featuring MILTON」は、エントリーレベルのテックワーカーが直面する激しいプレッシャーを批判的に検証する風刺モバイルゲームです。このシミュレーションでは、**1 回のタップは人生の 1 四半期を表し**、**1 つのグリッドマスは 1 ヶ年を表す**ことで、プレイヤーには急速な加齢と変動するメトリクスを管理させながら、過酷な現実を目撃させる仕組みとなっています。初期状態として Milton は 22 歳(Q1)、パフォーマンススコアが 50、バーンアウトが 10 の状態で始まり、高給与(年額 19 万ドル)と金銭的自由の欠如(退職永久資金 0%)、そして資産総額 0 が同時に存在する厳しい現実を描き出します。プレイヤーがこれらの制約の中で動き回りながら、企業が 0% のトラクションを示す中で、特定のアクションによって定義された明確な複数のエンディングへと至ります:その行為とは、**「Form HR-1099-RAT」の記入**、**「Exit Interview」への参加**、そして**「GO HOME」画面の表示**です。シミュレーション終了後、プレイヤーはその結果を 𝕏(X)に投稿し、自らの架空のキャリアの終焉をデジタル記録として残すことができます。最終的に、このプロジェクトは業界全体の課題である従業員の福祉、定着率の難しさ、一流テクノロジー企業で働く際の隠れたコストなどについて鋭い評論を行い、官方的な提携はないまま、現状の高い成長を志向する専門職モデルの持続可能性に疑問を投げかける魅力的な体験へと抽象的な企業データを転換します。

2026/07/09 0:19

Chatto はオープンソースになりました

## Japanese Translation: Chatto は、セルフホスト用に設計された新たにリリースされたオープンソースのグループチャットおよびチームチャットアプリケーションです。ユーザーは、`brew install chattocorp/tap/chatto` で Homebrew を使用して Linux (x86_64/ARM64)、macOS、Windows 上ですぐに試すことができます。その後、`chatto init` と `chatto run` を実行します。その核心的な強みは、コンパクトなパフォーマンス、堅牢なプライバシー、完全なデータ保護です:すべてのデータは静態で暗号化され、アカウント削除時にユーザー固有の鍵が完全に「破棄」され、データ痕跡は残りません。連邦システムとは異なり、Chatto はサードパーティの追跡がない単一サーバーのコミュニティモデルを運用し、クライアントは同時に複数のサーバーに直接接続できます。内蔵された音声通話、ビデオ通話、画面共有はすべてエンドツーエンドで暗号化され、インフラストラクチャのキャパシティに応じてスケーリングします。現在、production 使用のためにバージョン 0.4 が安定しており、Chatto は広告やベンダーロックインを回避しています。有料の「Chatto Cloud」サービスが間もなくヨーロッパ所有のインフラ上で開始され、広告なしでロックインなく安全なホスティングを提供し、自動スケーリング、夜間のバックアップ、ダウンタイムなしのアップグレード、セルフホストされたサーバーとの完全互換性を提供します。追加のリージョンは 2027 年初頭に予定されています。バージョン 0.5 は安全性機能、コンテンツモデレーション、クライアントの改良に焦点を当て、予想される 1.0.0 リリースに向けて進みます(注:新しいバージョンがロールアウトするにつれて破壊的変更が発生する可能性があります)。コミュニティサポートは Chatto HQ の専用の #self-hosting チャンネルで利用でき、リリースおよび早期 Cloud ベータへのアクセスに関する更新のために低ボリュームのニュースレター(〜1 封/月)を購読することもできます。この安全かつ広告なしのプラットフォームは、現代のマルチメディア機能を損なうことなくユーザーの主権を優先します。 ## Text to translate: Chatto is a newly released open-source group and team chat application designed for self-hosting. Users can immediately try it on Linux (x86_64/ARM64), macOS, or Windows via Homebrew with `brew install chattocorp/tap/chatto`, then run `chatto init` and `chatto run`. Its core strengths are compact performance, robust privacy, and full data protection: all data is encrypted at rest and per-user keys are completely "shredded" upon account deletion, leaving no data trails. Unlike federated systems, Chatto operates on a single-server community model with no third-party tracking; clients can connect directly to multiple servers simultaneously. Built-in voice, video calls, and screen-sharing are fully end-to-end encrypted and scale with infrastructure capacity. Currently stable at version 0.4 for production use, Chatto avoids ads and vendor lock-in. A paid "Chatto Cloud" service is launching soon on European-owned infrastructure, offering secure hosting without ads or lock-in, automatic scaling, nightly backups, zero-downtime upgrades, and full compatibility with self-hosted servers; additional regions are expected in early 2027. Version 0.5 will focus on safety features, content moderation, and client polishing, leading to the anticipated 1.0.0 release within 6–12 months (note: breaking changes may occur as new versions roll out). Community support is available at Chatto HQ via a dedicated #self-hosting channel, and users can subscribe to a low-volume newsletter (~1 email/month) for updates on releases and early Cloud beta access. This secure, ad-free platform prioritizes user sovereignty without compromising modern multimedia capabilities.

2026/07/09 3:00

Grok 4.5

## Japanese Translation: SpaceXAI は、コーディング、エージェンタスク、複雑な知識業務に特化して Cursor と共同開発された、現時点で最も高度なモデルである Grok 4.5 を発売しました。本モデルは、単一のプロンプトからエンドツーエンドのアプリケーションを構築する(太陽系など細部の模擬を含む)などの強力な能力を示していますが、主要なベンチマークでは 3 位にランクインしています:DeepSWE 1.0 で 62.0%、Terminal Bench 2.1 で 83.3%、SWE Bench Pro では解決率が 64.7% と、GPT-5.5 xhigh および Fable に及ばない結果となっています。本モデルは、数万台の NVIDIA GB300 GPU を使用し、高度なデータ選別技術と、トークンごとの知能に焦点を当てた強化学習戦略を採用することで、同等モデルと比較して約 4.2 倍のトークン効率を達成しています。 Grok 4.5 は、入出力トークンあたりそれぞれ 100 万トークンで 2 米ドルおよび 6 米ドルという高速サービスを提供しており、限定期間中の無料利用オファーも用意されています。現在、Excel リサーチや PowerPoint の図表作成を強化する目的で Grok Build、Cursor、SpaceXAI コンソールに統合されていますが、ヨーロッパ連合では 7 月中旬のローンチまでの間利用できません。

PostgreSQL の B-Tree インデックスを理解する:包括的ガイド~パート 1~ | そっか~ニュース