メインコンテンツまでスキップ
メインコンテンツまでスキップ

フルテキスト検索とフルテキストインデックスの使用

Experimental feature. Learn more.
Not supported in ClickHouse Cloud

フルテキストインデックスは、セカンダリインデックスの実験的なタイプで、StringまたはFixedStringカラムのための高速テキスト検索機能を提供します。フルテキストインデックスの主なアイデアは、「用語」とそれらを含む行とのマッピングを保存することです。「用語」は文字列カラムのトークン化されたセルです。たとえば、文字列セル「I will be a little late」はデフォルトで六つの用語「I」、「will」、「be」、「a」、「little」、「late」にトークン化されます。別のトークナイザの種類はn-グラムです。例えば、3-グラムトークン化の結果は21の用語「I w」、「 wi」、「wil」、「ill」、「ll 」、「l b」、「 be」などとなります。入力文字列が細かくトークン化されるほど、結果として得られるフルテキストインデックスは大きく、かつより有用になります。

注記

フルテキストインデックスは実験的であり、まだ本番環境での使用には適していません。将来的にはDDL/DQL構文やパフォーマンス/圧縮特性に関して後方互換性のない方法で変更される可能性があります。

使用法

フルテキストインデックスを使用するには、まず設定でそれを有効にします:

フルテキストインデックスは、次の構文を使用して文字列カラムに定義できます。

ここで、tokenizerはトークナイザを指定します:

  • defaultはトークナイザを「tokens('default')」に設定します。すなわち、非英数字文字に沿って文字列を分割します。
  • ngramはトークナイザを「tokens('ngram')」に設定します。すなわち、文字列を等しいサイズの用語に分割します。
  • noopはトークナイザを「tokens('noop')」に設定します。すなわち、各値自体が用語となります。

ngramサイズは、ngram_sizeパラメータを介して指定できます。これはオプションのパラメータです。以下のバリエーションが存在します:

  • ngram_size = NNが2から8の範囲内で、トークナイザを「tokens('ngram', N)」に設定します。
  • 指定しない場合:デフォルトのngramサイズは3を使用します。

最大行数は、オプションのmax_rows_per_postings_listを介して指定できます。このパラメータは、巨大なポスティングリストファイルを生成しないようにポスティングリストサイズを制御するために使用できます。以下のバリエーションが存在します:

  • max_rows_per_postings_list = 0:ポスティングリストあたりの最大行数に制限はありません。
  • max_rows_per_postings_list = MMは少なくとも8192である必要があります。
  • 指定しない場合:デフォルトの最大行数は64Kを使用します。

フルテキストインデックスは、テーブル作成後にカラムにドロップまたは追加できます。

インデックスを使用するには、特別な関数や構文は必要ありません。典型的な文字列検索述語は自動的にインデックスを利用します。例えば:

フルテキストインデックスは、Array(String)Array(FixedString)Map(String)、およびMap(String)タイプのカラムでも機能します。

他のセカンダリインデックスと同様に、各カラムパートには独自のフルテキストインデックスがあります。さらに、各フルテキストインデックスは内部的に「セグメント」に分割されます。セグメントの存在とサイズは一般的にユーザーには透明ですが、セグメントサイズはインデックス構築中のメモリ消費を決定します(例えば、2つのパーツがマージされるとき)。設定パラメータ「max_digestion_size_per_segment」(デフォルト:256 MB)は、新しいセグメントが作成される前に基盤となるカラムから読み込まれるデータ量を制御します。このパラメータを増やすことにより、インデックス構築中の中間メモリ消費が増加しますが、クエリを評価するためにチェックする必要のあるセグメントが少なくなるため、ルックアップパフォーマンスも向上します。

Hacker Newsデータセットのフルテキスト検索

テキストがたくさんある大規模データセットに対するフルテキストインデックスのパフォーマンス向上を見てみましょう。人気のあるHacker Newsウェブサイトの2870万行のコメントを使用します。以下はフルテキストインデックスのないテーブルです:

2870万行はS3のParquetファイルにあり、これをhackernewsテーブルに挿入します:

commentカラムで ClickHouse(さまざまな大文字と小文字のバリエーション)を探す以下の単純な検索を考えてみましょう:

クエリの実行に3秒かかることに注意してください:

次に、ALTER TABLEを使用して、commentカラムの小文字に対してフルテキストインデックスを追加し、それをマテリアライズします(これはしばらく時間がかかる場合があります。マテリアライズされるまで待ってください):

同じクエリを実行します...

...そしてクエリが4倍速く実行されることに気付きます:

また、複数の用語、すなわち、選言または共言で検索することもできます:

注記

他のセカンダリインデックスとは異なり、フルテキストインデックスは(現時点では)行番号(行ID)にマッピングされます。この設計の理由はパフォーマンスです。実際には、ユーザーはしばしば複数の用語を一度に検索します。たとえば、フィルタ述語 WHERE s LIKE '%little%' OR s LIKE '%big%' は、「little」と「big」の用語の行IDリストの和を形成することにより、フルテキストインデックスを使用して直接評価できます。これにより、インデックス作成時に提供されるパラメータ GRANULARITY は意味を持たなくなります(将来的には構文から削除される可能性があります)。