Какие поля выбрать для сортировки кластерного индекса
Что проверяют
Понимаете ли вы, что кластерный индекс задаёт физический порядок строк, и выбор ключа влияет не только на чтение, но и на вставку и объём. Для data-специальности следом часто спрашивают про аналитические хранилища: как выбрать ORDER BY в ClickHouse или ключ кластеризации в облачном DWH.
Как отвечать
Начните с того, что кластерный порядок у таблицы один, поэтому его отдают под самый частый сценарий чтения. Критерии для OLTP (SQL Server, InnoDB в MySQL):
- узкий ключ: ключ кластерного индекса копируется в каждый вторичный индекс, и широкий составной ключ раздувает их все;
- монотонно растущий:
bigint identityили время вставки пишутся в конец, а случайныйUUID v4даёт разбиение страниц и фрагментацию; - неизменяемый: смена значения ключа означает перенос строки на другое место;
- под диапазонные запросы: если отчёты читают «заказы клиента за период», порядок
(customer_id, order_date)превращает их в последовательное чтение.
В аналитике логика другая. В ClickHouse ключ сортировки ORDER BY в MergeTree задаёт разреженный индекс по гранулам, и первыми ставят колонки из частых фильтров с низкой кардинальностью, например (event_type, toDate(ts), user_id). Так лучше отсекаются гранулы и лучше сжимаются данные. В BigQuery кластеризация тоже работает на отсечение блоков, колонок в ней не больше четырёх; в Snowflake ключ кластеризации советуют держать из трёх-четырёх выражений.
Закончите тем, что ключ проверяют на реальных запросах: по EXPLAIN и по числу прочитанных строк или гранул, а не выбирают на глаз.
Где спотыкаются
Утверждают, что кластерный ключ обязан быть уникальным. SQL Server допускает неуникальный и сам добавляет скрытый уникализатор, так что уникальность желательна, но не обязательна.
Переносят правило «высокая кардинальность первой» на ClickHouse. Там поле с миллионами значений на первом месте почти лишает смысла остальные колонки ключа.
Берут случайный GUID ключом кластерного индекса в OLTP-таблице, а потом разбираются с фрагментацией и медленной вставкой.