TimescaleDB が時系列データを圧縮する方法

2026/06/16 2:29

TimescaleDB が時系列データを圧縮する方法

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

要約

Japanese Translation:

TimescaleDB の hypercore エンジンは、行ベースおよび列ベースのストレージ形式を賢く組み合わせることで、時系列データについて最大 98% の圧縮率を実現します。新しいデータは標準的な行形式で入力され、古いチャンクが時間経過に伴い自動的に高圧縮な列ベース形式に変換されます。Gorilla XOR、delta-of-delta、ラン長符号化などの特化的アルゴリズムが横方向のパターンを効率的に捉え、ストレージフットプリントおよび I/O 要求を大幅に低減します。PostgreSQL の TOAST が個別の大規模値を扱うのに対し、hypercore は分析クエリ(範囲スキャンや集約など)においてより少ないバイト数を読み取り、高速に実行できるように大規模データセットを最適化します(実世界のテストでは 28〜42 倍の改善が確認されています)。これらの利点を最大化するには、

segmentby
および
orderby
を使用してセグメントを構成し、各チャンクに十分な行数を含めるようにしてください(理想的には各チャンクあたり 100 以上のあるセグメント値を持つことを推奨します)。このハイブリッドシステムは長期的な保持プロジェクトにおけるストレージコストを大幅に低下させますが、更新時に実行される必要な復号化サイクルにより、ポイントルックアップや直接の行修訂が若干遅延する可能性がある点にご注意ください。

本文

TimescaleDB の圧縮:仕組み、設定、パフォーマンス向上ガイド

TimescaleDB は時系列データを最大 98% 圧縮する独自の技術を持っています。本稿では、その仕組み、設定方法、そして PostgreSQL 標準機能との違いを整理します。


1. TimescaleDB の圧縮 vs. PostgreSQL TOAST

PostgreSQL に内蔵されている

TOAST
(超大属性保存技術)と TimescaleDB の圧縮は、本質的に異なる問題を解決するための補完的な機構です。

基本の違い

特徴TOAST (Vanilla PostgreSQL)TimescaleDB Hypercore
設計目標個別の大きな値(2 KB を超える文字列など)を処理する時系列データの行間パターンに最適化された圧縮を実現する
トリガー行数が
TOAST_TUPLE_THRESHOLD
(~2 KB) を超える場合
チャンクごとのポリシー(例:データ作成後 7 日)で自動発動
サポートデータ型可変長のみ (
text
,
jsonb
,
bytea
,
numeric
)
すべてのデータ型に対応
アルゴリズムpglz(デフォルト)、lz4(オプション)ハイブリッド: デルタ符号化、ランレングス (RLE)、XOR ベースなど
圧縮粒度値単位 (1 値 = 1 バイトストリーム)バッチ単位 (~1000 行をまとめる)
データ構造活用なし(不透明なバイト列扱い)はい(数値構造、単調性、反復性を活用)

圧縮比率の比較(推定)

データタイプTOAST 標準 (PG14 以前/未設定)TimescaleDB Hypercore
センサー浮動小数点~1.0× (圧縮なし)10-20×
タイムスタンプ~1.0× (圧縮なし)50-100×
テキスト2-3×5-10×

注意: TOAST は浮動小数点や固定長整数には効きません。IoT ワークロードなどで TOAST が使えない場合、TimescaleDB は 10-100 倍の圧縮を実現します。


2. Hypercore エンジンとカラム指向ストレージ

TimescaleDB は新しいデータが高速な「行指向」形式で蓄積される一方、古いデータは自動的にカラム指向に変換されます。これを

hypercore
というエンジンと呼びます。

ハイブリッド動作のメリット

  • 高速な INSERT/UPDATE: 新規データは行指向で保存され、OLTP に最適化されています。
  • 高速な分析クエリ: 古いデータ(チャンク)はカラム指向圧縮形式に変換され、読み取り I/O を最小化します。

行からの変換プロセス

圧縮処理では、行を最大 1000 行ずつのバッチにグループ化し、各バッチを圧縮された単一のエントリとして保存します。

【カラム指向バッチの特徴】

  • 配列化: カラムごとに最大 1000 個の値を持つ配列として格納されます(例:
    temperature[1000]
    )。
  • カラムマジョリティ: 同一列の値を連続して配置するため、特定の列のみを参照する際のスキャンが高速化します。
  • 高度なアルゴリズム適用: デルタ符号化やランレングス符号化 (RLE) を列レベルで適用し、I/O コストを削減します。

3. 主要な圧縮アルゴリズムの仕組み

TimescaleDB は各データ型の特性に応じて最適なアルゴリズムを選択します。代表的な手法は以下の通りです。

① デルタ符号化 (Delta Encoding)

値の変化分(Delta)のみを保存し、絶対値を削減します。

  • 原理: 前の値からの差分 (
    +0.2
    ,
    -0.1
    ) を保存する。
  • 適用対象: 浮動小数点データ(温度、圧力など)、数値が変動する場合。

② デルタ・オブ・デルタ符号化 (Delta-of-Delta Encoding)

時間間隔が規則的な場合、変化分の差分をさらに圧縮します。

  • 原理: 「+5 秒」の変化が続く場合は
    +0 秒
    と表せるため、データ量が急減します。
  • 適用対象: タイムスタンプ、定期的なサンプリングデータ。

③ ランレングス符号化 (Run-Length Encoding, RLE)

重複する値を「値」×「回数」として保存します。

  • 原理:
    MACHINE_001
    が 5 回続く場合、文字列を 5 回書く代わりに
    MACHINE_001 × 5
    と保存します。
  • 適用対象: デバイス ID (
    machine_id
    )、センサー種別 (
    sensor_type
    ) などの重複が多いカラム。

圧縮技術サマリー

カラム例推奨手法表現例
timeデルタ・オブ・デルタ
12:00:00
,
+5s
,
0
,
0
...
machine_idランレングス符号化 (RLE)
MACHINE_001 × 5
sensor_typeランレングス符号化 (RLE)
temp × 5
valueデルタ符号化
72.5
,
+0.2
,
-0.3
...

重要: アルゴリズムは万能ではありません。高エントロピー(一意な値が多い)なカラム(例:UUID)では辞書圧縮が効果的ですが、逆に単純に不変なデータであっても適切な手法が選ばないと圧縮効率は下がります。TimescaleDB は自動的に最適な組み合わせを選定します。


4. 重要な設定パラメータ

圧縮機能の有効化には、以下の 2 つのパラメータを適切に設定することが不可欠です。これらは**「チャンクの分割基準」と「ソート順」**を決めるためです。

パラメータ定義

  1. segmentby
    : チャンク全体で値が共有されるカラム(例:
    machine_id
    )。
    • 同じ
      segmentby
      値を持つ行は物理的に近接して保存されます。
    • プランナーはこの情報を使って、対象外のチャンクをスキップします(全走査回避)。
  2. orderby
    : チャンク内のソート順序(通常は
    time DESC
    )。
    • データを時間順に並べることで、デルタ符号化や RLE の効用を最大化します。

SQL 設定例

ALTER TABLE iot_sensor_data SET (
  timescaledb.compress = true,
  timescaledb.segmentby = 'machine_id', -- 分割基準カラム
  timescaledb.orderby   = 'time DESC'   -- ソート順(過去からのソート推奨)
);

-- 7 日以上経過したデータを自動的に圧縮するポリシー適用
SELECT add_columnstore_policy(
    'iot_sensor_data', 
    after => INTERVAL '7 days'
);

設定時のルール(基数制約)

アルゴリズムが機能するためには、圧縮対象のチャンク内で十分な「類似した値」が必要です。

  • 推奨範囲: チャンクごとに
    segmentby
    のユニーク値数が 100 - 10,000 程度あること。
  • 最低ライン: セグメント(バッチ)あたりの行数が 100 行以上
  • 注意点: センサー数(基数)が高すぎると、各センサーのデータ量が少なくなりすぎるため圧縮効率が落ちます。

5. パフォーマンスへの影響

「圧縮はクエリを遅くするか?」という疑問に対して、答えは状況によって異なります

✅ 高速化するケース(ワークロードの過半数)

  • 集計処理: 時間範囲内の
    SUM
    ,
    AVG
    ,
    MAX
    など。
  • 範囲スキャン: 大規模な日付範囲検索。
  • フィルタ済みクエリ:
    segmentby
    カラム(例:特定の ID)で絞る場合。

理由: I/O コストが 10-20 倍削減されるため、ディスク読み込みとメモリ使用量が大幅に減少します。

例: 圧縮前の 1 GB データ読み取り vs. 圧縮後の 50 MB 読み取り = 圧倒的に高速

⚠️ 低速化するケース(時系列では稀)

  • 単一行ポインタルックアップ:
    time = '...' AND id = X
    のような極めて限定された検索。
  • 更新・削除操作 (UPDATE/DELETE): デコンプレッション → 変更 → リコンプレッションという処理コストがかかります。
  • 高基数フィルタなし:
    segmentby
    カラムを指定しない場合の全テーブルスキャン。

6. 実際のデータベースへの設定と検証

以下は IoT センサー監視システムへの適用例です。

① 自動圧縮の設定

-- 7 日以上前のデータを自動的にカラムストレージに変換するポリシー
SELECT add_columnstore_policy(
    'iot_sensor_data', 
    after => INTERVAL '7 days'
);

-- チャンクの詳細確認(圧縮状態の確認)
SELECT chunk_name, is_compressed, range_start,
       pg_size_pretty(total_bytes) AS size
FROM chunks_detailed_size('iot_sensor_data')
WHERE timescaledb_hypertable = true 
  AND is_compressed = true;

② 圧縮による高速化の実績(例)

ある MQTT データセットでの比較結果(Rowstore vs Columnstore):

メトリックRowstore (未圧縮)Columnstore (圧縮後)改善率
サイズ2.3 GB7.2 MB約 43× の削減
実行時間10.2 ms0.36 ms約 28× の高速化
  • 理由:
    segmentby
    に基づくメタデータインデックスにより、対象チャンクのみを読み取ることが可能になりました。

③ クエリプラン分析 (
EXPLAIN ANALYZE
)

圧縮されたチャンク(Columnstore)では、B-tree インデックスの代わりに、TimescaleDB が自動生成した

(segmentby_col, min_val, max_val)
というメタインデックスが使われます。これにより、不要なチャンクをスキップして高速に結果を検出できます。


7. 適用前のチェックリスト

設定を行う前に、現在のデータ分布を確認することをお勧めします。

segmentby
の適性確認方法

-- チャンク内の各行の行数分布を確認
WITH per_id AS (
    SELECT id, count(*) AS n
    FROM _timescaledb_internal._hyper_X_Y_chunk -- 実際のチャンク名を指定してください
    GROUP BY id
)
SELECT 
    SUM(count) FILTER (WHERE n < 100)  AS low_volume_count,
    SUM(count) FILTER (WHERE n >= 100) AS high_volume_count
FROM per_id;
  • 結果:
    low_volume_count
    が非常に多い場合(例:ID ごとの行数が 100 未満)、現在の
    segmentby
    設定では圧縮効率が下がる可能性があります。

まとめ

TimescaleDB の圧縮機能は、単なるサイズ削減だけでなく、時系列データの分析クエリを劇的に高速化させる技術です。

  • 仕組み: 古いデータは自動的にカラム指向のハイブリッド形式(
    hypercore
    )へ変換され、10-100 倍の圧縮を実現します。
  • 設定の鍵:
    timescaledb.segmentby
    timescaledb.orderby
    を正しく設定し、データ分布がアルゴリズムに適した範囲にあるか確認してください。
  • 効果: IoT や生産性モニタリングなどで長期間データを保持する際、ストレージコストとクエリ速度の両面で優れています。

具体的な導入設計やアーキテクチャサポートが必要な場合は、お気軽にご相談ください。

同じ日のほかのニュース

一覧に戻る →

2026/06/16 5:00

LinkedIn の雇用オファーに含まれた裏口

## 日本語訳: 提供されたテキストは、読めるコンテンツではなく完全に破損したバイナリデータからなるものであり、ニュース、事実、エンティティ(製品名、日付、組織など)、または論理的構造は一切含んでいません。入力内に理解可能な単語や文が存在しないため、背景コンテキスト、将来の予測、または潜在的な影響を特定することはできません。その結果、特定の数字を抽出したり、IT 記事のための妥当な箇条書きを生成したり、意味のある要約を導き出すことは不可能であり、このデータは修復されるまで、あるいは正当なテキストで置換されるまでは静的ノイズとして機能し、分析に価値を持ちません。

2026/06/16 7:37

Wi-Fi スマート電球に内蔵された禁書図書館

## 日本語翻訳: 「Banned Book Library」プロジェクトは、安価な WiFi スマートボールを分散型で検閲耐性のある禁書アーカイブに変換し、不安定なクラウドサービスよりもローカルコントロールを重視し、Cory Doctorow の情報レジリエンス哲学と整合性を保ちます。ESP32C3 チップの限られた 4MB フラッシュストレージに対処し、外部メモリカード用の困難なハンダ付けを避けるために、開発者は Arduino IDE と ESP-IDF を用いてファームウェアをカスタマイズしました。具体的にはパーティションテーブルを変更して電子書籍用にスペースを割り当てるよう修正するとともに、Tasmota(ソースコードの複雑さから放棄された)に見られる平文で認証情報を格納するというセキュリティリスクを回避しています。本デバイスは、カスタム「safeboot」復旧メカニズムを備え、禁書理由とともに書籍リストを表示する Web インターフェースを内蔵しており、GPIO ピンを通じて LED の色温度を制御できる管理パネルも含まれています。DNS 劫奪を用いたキャプティブポータルを実装し、あらゆるデバイスからユーザーをローカルアーカイブへ誘導することで、物理的に分散されたネットワークによる情報レジリエンスを実現しています。今後のアップデートでは、AnalogWrite を用いた精密な RGB/ホワイト色制御や、ファイル共有のためのメッシュネットワーキングへの実験が含まれます。結局のところ、このプロジェクトは一般的なスマートホーム技術を堅牢なインフラストラクチャに転換し、日常のデバイスが重大なアーカイブ機能を受け持ち得ることを示すとともに、小容量というハードウェアの制約を特徴へと高め、保管者に最も重要な作品のみを選定するよう促しています。

2026/06/16 0:13

イロフ 1.0

## Japanese Translation: iroh ネットワークは、それ以前の 65 バージョンに続く初となる安定リリースとしてのバージョン 1.0 を正式にローンチし、インターネット全体で安全な localhost のように動作する革命的な「key でダイヤル」システムを導入します。このマイルストーンでは、不安定な IP アドレスをユーザーが制御するキーに置き換え、複雑なルーティングに依存せずにデバイス間での直接かつ暗号化された接続を可能にします。ネットワークは巨大なスケーラビリティを実証しており、たった 30 日で 2 億以上のエンドポイントを作成し、安全な動画ストリーミングやエージェント間の通信、大規模言語モデルのトレーニングなど、多様な用途に数百万のデバイスを支えています。IETF のドラフトや QUIC マルチパスといったオープン標準を基盤とし、ローカルフースト設計によりインターネット接続がなくても堅牢なコネクティビティを提供します。開発者にとっての大きな影響として、Python、Node.js、Swift、Kotlin への公式 FFI サポートが追加され、安定した異言語間通信が保証されています。特に、1.0 API はエンドポイント間の通信がマイナーバージョンの変更や使用されるプログラミング言語に関係なく確保されることを保証します。さらに、デバイス同士の直接転送によりクラウドホップが 95% 削減され、データエグレスコストの大幅な低下が可能となるだけでなく、Bluetooth Low-Energy など新たなトランSPORT を実装できます。前マイナーバージョンを使用しているユーザーは、2026 年 12 月 31 日(パブリックリレーサポート終了日)までにアップグレードすることを推奨され、安定性を維持するためです。問題が発生している場合は、バグレポートの前に更新して問題が持続するかを確認してください。