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

フルテキストインデックスを使用したフルテキスト検索

Experimental feature. Learn more.
Not supported in ClickHouse Cloud

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

注記

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

使用法

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

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

注記

以前のバージョンのClickHouseでは、対応するインデックスタイプ名はinvertedでした。

Nはトークナイザーを指定します。

  • full_text(0)(または短縮形: full_text())はトークナイザーを「トークン」に設定し、つまり空白で文字列を分割します。
  • full_text(N)Nが2から8の間だと、トークナイザーを「ngrams(N)」に設定します。

ポスティングリストの最大行数は、第二引数として指定できます。このパラメーターは、巨大なポスティングリストファイルの生成を避けるためにポスティングリストのサイズを制御するために使用できます。以下のバリエーションがあります。

  • full_text(ngrams, max_rows_per_postings_list):指定されたmax_rows_per_postings_listを使用します(0でないと仮定します)
  • full_text(ngrams, 0):ポスティングリストの最大行数に制限なし
  • full_text(ngrams):デフォルトの最大行数(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パラメーターは意味がなくなります(将来的には構文から削除される可能性があります)。