Перейти к основному содержимому
Перейти к основному содержимому

Первичные индексы

Ищете подробности об индексации?

Эта страница представляет разреженный первичный индекс ClickHouse, как он строится, как работает и как помогает ускорять запросы.

Для более продвинутых стратегий индексации и более глубоких технических деталей, смотрите глубокое погружение в первичные индексы.

Как работает разреженный первичный индекс в ClickHouse?


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

Создание разреженного первичного индекса

Чтобы проиллюстрировать, как строится разреженный первичный индекс, мы используем таблицу uk_price_paid_simple вместе с некоторыми анимациями.

Как напоминание, в нашей ① примерной таблице с первичным ключом (town, street), ② вставленные данные ③ хранятся на диске, отсортированные по значениям колонок первичного ключа и сжаты, в отдельных файлах для каждой колонки:



Для обработки данные каждой колонки ④ логически делятся на гранулы — каждая из которых охватывает 8,192 строки — которые являются наименьшими единицами, с которыми работает механика обработки данных в ClickHouse.

Эта структура гранул также делает первичный индекс разреженным: вместо индексации каждой строки, ClickHouse хранит ⑤ значения первичного ключа только из одной строки на гранулу — а именно, из первой строки. Это приводит к тому, что на гранулу приходится одна запись индекса:



Благодаря своему разрежению первичный индекс достаточно мал, чтобы полностью поместиться в памяти, что обеспечивает быстрое фильтрацию для запросов с предикатами по колонкам первичного ключа. В следующем разделе мы покажем, как он помогает ускорять такие запросы.

Использование первичного индекса

Мы схематически покажем, как разреженный первичный индекс используется для ускорения запросов с помощью другой анимации:



① Пример запроса включает предикат по обеим колонкам первичного ключа: town = 'LONDON' AND street = 'OXFORD STREET'.

② Чтобы ускорить запрос, ClickHouse загружает первичный индекс таблицы в память.

③ Затем он сканирует записи индекса, чтобы определить, какие гранулы могут содержать строки, соответствующие предикату, другими словами, какие гранулы нельзя пропустить.

④ Эти потенциально релевантные гранулы затем загружаются и обрабатываются в памяти, вместе с соответствующими гранулами из любых других колонок, необходимых для запроса.

Мониторинг первичных индексов

Каждая часть данных в таблице имеет свой собственный первичный индекс. Мы можем просмотреть содержимое этих индексов, используя табличную функцию mergeTreeIndex.

Следующий запрос перечисляет количество записей в первичном индексе для каждой части данных нашей примерной таблицы:

Этот запрос показывает первые 10 записей из первичного индекса одной из текущих частей данных. Обратите внимание, что эти части постоянно сливаются в фоновом режиме в более крупные части:

Наконец, мы используем оператор EXPLAIN, чтобы увидеть, как первичные индексы всех частей данных используются для пропуска гранул, которые не могут содержать строки, соответствующие предикатам примерного запроса. Эти гранулы исключаются из загрузки и обработки:

Обратите внимание, что строка 13 вывода EXPLAIN показывает, что только 3 из 3,609 гранул по всем частям данных были выбраны для обработки анализом первичного индекса. Оставшиеся гранулы были полностью пропущены.

Мы также можем наблюдать, что большая часть данных была пропущена, просто запустив запрос:

Как показано выше, было обработано всего около 25,000 строк из примерно 30 миллионов строк в примерной таблице:

Основные выводы

  • Разреженные первичные индексы помогают ClickHouse пропускать ненужные данные, идентифицируя, какие гранулы могут содержать строки, соответствующие условиям запроса по первичным ключевым колонкам.

  • Каждый индекс хранит только значения первичного ключа из первой строки каждой гранулы (гранула по умолчанию содержит 8,192 строки), что делает его компактным и способным помещаться в памяти.

  • Каждая часть данных в таблице MergeTree имеет свой собственный первичный индекс, который используется независимо во время выполнения запроса.

  • Во время выполнения запросов индекс позволяет ClickHouse пропускать гранулы, снижая ввод-вывод и использование памяти, одновременно ускоряя производительность.

  • Вы можете проверять содержимое индекса, используя табличную функцию mergeTreeIndex, и контролировать использование индекса с помощью оператора EXPLAIN.

Где найти дополнительную информацию

Для более глубокого ознакомления с тем, как работают разреженные первичные индексы в ClickHouse, включая то, как они отличаются от традиционных базовых индексов и лучшие практики их использования, ознакомьтесь с нашим подробным глубоким погружением в индексацию.

Если вас интересует, как ClickHouse обрабатывает данные, выбранные с помощью сканирования первичного индекса, в высокопараллельном режиме, ознакомьтесь с руководством по параллелизму запросов здесь.