cached Dictionaryレイアウト型では、固定数の cell を持つ cache にDictionaryを格納します。
これらの cell には、頻繁に使用される要素が格納されます。
Dictionaryキーは UInt64 型です。
Dictionaryを検索するときは、まず cache が検索されます。データの各 block について、cache に存在しないキー、または古くなったキーは、SELECT attrs... FROM db.table WHERE id IN (k1, k2, ...) を使用してソースへ要求されます。取得したデータはその後 cache に書き込まれます。
これは、キーのルックアップ、つまり dictGet やその他のDictionary関数に適用されます。SELECT ... FROM <dictionary> でDictionaryをtable として読み取る場合は異なります。cache にはどのキーが存在するかの記録がないため、この読み取りでは、その時点で cache に存在し、かつ値を保持している cell のみが列挙され、キーに対する WHERE は、取得するキーのリストではなく、それらの cell に対する通常の filter となります。cache に存在しないキーは、WHERE に何を記述してもこの方法では発見できません。ルックアップは行われたもののソースで見つからなかったキーも表示されません。cache はそのミスをデフォルト cell として記憶し、table としての読み取りはデフォルト cell をスキップするためです。また、cache に存在する cell もソースと無関係ではありません。期限切れの cell は dictGet と同じ経路で読み取られるため、ソースへ再度要求されます。これは同期的に行われ、allow_read_expired_keys が有効な場合は非同期に行われます。
dictGet を使用してください。なお、direct Dictionaryを table として読み取る場合も、キー指定による fetch にはなりません。SELECT ... FROM <dictionary> WHERE key IN (...) は、ClickHouse がキーの filter をDictionaryにプッシュダウンしないため、ソース全体を読み込んでから filter を適用します。Dictionaryを table として読み取る場合は、flat や hashed のようにDictionary全体を保持するレイアウトを使用してください。
Dictionary内にキーが見つからない場合は、cache 更新用の task が作成され、更新 queue に追加されます。更新 queue のプロパティは、max_update_queue_size、update_queue_push_timeout_milliseconds、query_wait_timeout_milliseconds、max_threads_for_updates の各設定で制御できます。
cache Dictionaryでは、cache 内のデータの有効期限 lifetime を設定できます。cell にデータを読み込んでから lifetime を超える時間が経過すると、その cell の値は使用されず、キーは期限切れになります。そのキーは、次回必要になったときに再度要求されます。この動作は allow_read_expired_keys 設定で構成できます。
これは、Dictionaryの格納方法の中で最も効率が低いものです。cache の速度は、適切な設定と使用シナリオに大きく依存します。cache 型Dictionaryが十分に高い性能を発揮するのは、ヒット率が十分高い場合のみです (推奨は 99% 以上) 。平均ヒット率は system.dictionaries table で確認できます。
allow_read_expired_keys 設定が 1 の場合 (デフォルトは 0) 、Dictionaryは非同期更新をサポートできます。クライアントがキーを要求し、それらがすべて cache 内にあるものの一部が期限切れの場合、Dictionaryは期限切れのキーをクライアントに返しつつ、それらをソースに非同期で要求します。
cache の性能を向上させるには、LIMIT を含むサブクエリを使用し、Dictionaryの外側で関数を呼び出してください。
すべての種類のソースがサポートされています。
設定例:
- DDL
- 構成ファイル
十分に大きな cache サイズを設定してください。cell 数の選定には試行が必要です:
- 適当な値を設定します。
- cache が完全に埋まるまでクエリを実行します。
system.dictionariestable を使ってメモリ消費量を評価します。- 必要なメモリ消費量に達するまで、cell 数を増減します。
このレイアウトのソースとして ClickHouse を使用することは推奨されません。Dictionary のルックアップにはランダムなポイント read が必要ですが、これは ClickHouse が最適化しているアクセスパターンではありません。