Перейти к основному содержанию
На этой странице собраны практические рекомендации по выбору подходящей структуры словаря, по пониманию того, в каких случаях словари работают быстрее, чем JOIN, а в каких — нет, а также по мониторингу их использования. Введение в словари с подробными примерами см. в основном руководстве по словарям.

Когда использовать словари вместо JOIN-ов

Словари лучше всего подходят, когда одна из сторон JOIN — это таблица соответствий, которая помещается в память. При обычном JOIN ClickHouse строит хеш-таблицу на основе правой части, а затем выполняет по ней поиск для левой — даже если позже большинство строк будет отброшено фильтрами WHERE. Хотя в последних версиях (24.12+) во многих случаях фильтры применяются до JOIN-ов, это не всегда устраняет накладные расходы. При использовании словаря вы вызываете dictGet прямо в выражении, поэтому поиск выполняется только для строк, которые уже прошли фильтрацию. Однако dictGet подходит не всегда. Если вам нужно вызывать dictGet для большой доли строк таблицы — например, в условии WHERE, таком как dictGet('dict', 'elevation', id) > 1800 — лучше использовать обычный столбец с нативными индексами. ClickHouse может использовать PREWHERE, чтобы пропускать гранулы для обычного столбца, а dictGet вычисляется построчно и не использует индексы. Общее практическое правило:
  • Используйте словари вместо JOIN-ов с небольшими таблицами измерений, когда ключ для поиска уже доступен.
  • Используйте обычные столбцы и индексы, когда нужно фильтровать по найденному значению для большого числа строк.

Выбор структуры

Конструкция LAYOUT задаёт внутреннюю структуру данных словаря. Все доступные структуры описаны в справочнике по структурам. При выборе структуры используйте следующие рекомендации:
  • flat — самая быстрая структура (простой поиск по смещению в массиве), но ключи должны иметь тип UInt64 и по умолчанию ограничены 500 000 (max_array_size). Лучше всего подходит для монотонно возрастающих целочисленных ключей в таблицах малого и среднего размера. Разреженное распределение ключей (например, значения 1 и 500 000) приводит к неэффективному использованию памяти, поскольку размер массива определяется максимальным ключом. Если вы упираетесь в предел 500k, это сигнал перейти на hashed_array.
  • hashed_array — рекомендуемая структура по умолчанию для большинства сценариев. Хранит атрибуты в массивах, а хеш-таблица сопоставляет ключи с индексами массива. Почти так же быстра, как hashed, но эффективнее использует память, особенно при большом числе атрибутов.
  • hashed — хранит весь словарь в хеш-таблице. Может быть быстрее, чем hashed_array, если атрибутов очень мало, но потребляет больше памяти по мере увеличения их числа.
  • complex_key_hashed / complex_key_hashed_array — используйте их, когда ключи нельзя привести к UInt64 (например, ключи типа String). Для них характерны те же компромиссы по производительности, что и для вариантов без составного ключа.
  • sparse_hashed — снижает использование памяти по сравнению с hashed, но ценой дополнительной нагрузки на CPU. Редко бывает лучшим выбором — эффективен только при наличии одного атрибута. В большинстве случаев лучше подходит hashed_array.
  • cache / ssd_cache — кэшируют только часто используемые ключи. Полезны, когда весь набор данных не помещается в памяти, но при промахах кэша поиск может обращаться к источнику. Не рекомендуются для рабочих нагрузок, чувствительных к задержкам.
  • direct — выполняет запрос к источнику для каждого поиска без хранения данных в памяти. Используйте, когда данные меняются слишком часто для кэширования или когда словарь слишком велик, чтобы целиком поместиться в памяти.

Мониторинг использования словарей

Отслеживайте использование памяти и состояние словарей с помощью таблицы system.dictionaries:
Ключевые столбцы:
  • bytes_allocated — объём памяти, который использует словарь. Словари хранят данные в несжатом виде, поэтому это значение может быть значительно больше сжатого размера таблицы.
  • hit_rate и found_rate — полезны для оценки эффективности структуры cache.
  • last_exception — проверьте это поле, если словарь не удаётся загрузить или обновить.
Последнее изменение 25 июня 2026 г.