Skip to main content
仮想索引は、実際に構築したり保存したりすることなく MergeTree ファミリーのテーブルにアタッチできる、セッションスコープの仮想的なスキップ索引です。これらは現在のセッション内にのみ存在し、実際のスキップ索引がクエリにどのような影響を与えるかを見積もるために EXPLAIN WHATIF で使用されます。通常は、スキップ率 (スキップ可能なマークの割合) や、マーク数およびバイト数に基づくおおよそのコストを見積もります。 仮想索引を使うと、ディスク上にマテリアライズするコストをかける前に、候補となる索引を評価できます。

CREATE HYPOTHETICAL INDEX

構文は ALTER TABLE ... ADD INDEX と同様ですが、索引は構築も書き込みもされず、現在のセッションでは索引の定義だけが保存されます。
  • name — 索引名。このセッションでは、(database, table) 内で一意である必要があります。
  • expression — 索引対象のカラムまたは式です。
  • TYPE typeminmax, set(N), bloom_filter(p), ngrambf_v1(...), tokenbf_v1(...)textvector_similarity はサポートされておらず、CREATE 時に拒否されます。これは、実際の ALTER TABLE ... ADD INDEX の検証が、セッション専用ストアでは再現できないテーブルレベルの設定に依存しているためです。
  • GRANULARITY value — インデックスグラニュールあたりのデータグラニュール数。デフォルトは 1 です。
ターゲットテーブルは、Atomic データベース内の MergeTree ファミリーのテーブルである必要があります (UUID を持っている必要があります) 。UUID を持たないテーブル — たとえば従来の Ordinary データベース内のテーブルや、旧構文の MergeTree — は拒否されます。これは、セッションストアが仮想索引をテーブル UUID をキーとして管理するためです。

EXPLAIN WHATIF を使用した仮想索引の評価

仮想索引は、定義しただけでは何の効果もありません。クエリにどのような影響を与えるかを確認するには、代表的な SELECT に対して EXPLAIN WHATIF を実行します。この推定では、各候補索引の適用可否、読み取られるマーク数、結果として得られるスキップ率、さらにその推定がどのように算出されたか (empiricalstatistical、または applicability_only) が示されます。
結果:
est_bytes はテーブルの平均行サイズに基づく推定値であるため、正確な値はストレージや圧縮によって変わります。 メモリ内での実測スキャンを省略し、代わりに カラム STATISTICS から推定するには、まず対象のカラムでそれらを定義し (デフォルトでは無効です) 、materialize mutation が完了するのを待ってから、empirical path を無効にします:
出力スキーマと設定の詳細については、EXPLAIN WHATIF のリファレンスを参照してください。

DROP HYPOTHETICAL INDEX

現在のセッション内の仮想索引を削除します。

DROP ALL HYPOTHETICAL INDEXES

テーブルに関係なく、現在のセッションで定義されているすべての仮想索引を削除します。

スコープと有効期間

  • 仮想索引は現在のセッションにのみ存在します。ほかのセッションからは見えず、セッションが終了すると破棄されます。
  • これを定義または削除しても、実際の索引が構築されることはなく、そのテーブルに対する通常のクエリにも影響しません。EXPLAIN WHATIF は、候補となる索引をメモリ内に構築するためにテーブルデータを読み取ります。このスキャンは、セッションの読み取り制限とクォータに計上されます。
  • 現在のセッションの仮想索引は、system.hypothetical_indexes で確認できます。

制限事項

textvector_similarity の候補は、実際の検証がセッション専用ストアでは再現できないテーブルレベルの設定に依存するため、CREATE HYPOTHETICAL INDEX の時点で却下されます。 EXPLAIN WHATIF は、FINAL を含むクエリに対しては status: not_applicable を返し (スキップ索引の pruning が PrimaryKeyExpand と相互作用するため) 、クエリがプロジェクションから処理される場合は NOT_IMPLEMENTED エラーになります (親テーブルの索引はプロジェクション パーツには materialized されません) 。 経験的な skip_ratio``は**上限**です。これは、読み込み対象として残った各グラニュールを個別に数えており、seek-gap の coalescing(merge_tree_min_rows_for_seek/merge_tree_min_bytes_for_seek)や、選言的な(OR`) predicate のもとで候補を既存のスキップ索引と組み合わせるケースはモデル化していません。そのため、実際に materialized された索引では、読み込み量がわずかに多くなることもあれば、この推定では pruning されないケースで pruning されることもあります。

必要な権限

CREATE HYPOTHETICAL INDEX には、索引式で参照されるカラムに対する SELECT 権限が必要です。EXPLAIN WHATIF ではそれらのカラムが実際に読み取られるため、カラムレベルの SELECT (たとえば GRANT SELECT(b)) で十分です。 DROP HYPOTHETICAL INDEX および DROP ALL HYPOTHETICAL INDEXES には、追加の権限は必要ありません。これらはセッションローカルなストアからエントリを削除するだけです。

関連項目

最終更新日 2026年7月23日