Какой параметр использовать для партицирования, который не меняется со временем и помогает оптимизировать запрос
Что проверяют
Понимаете ли вы, как база выбирает партиции и почему ключ должен быть неизменным. Хороший ответ связывает три требования: ключ не меняется после вставки, есть почти в каждом запросе и распределяет данные равномерно. Следом спросят, что будет, если ключ всё-таки обновить, и как это отражается на коде сервиса.
Как отвечать
Разберите на примере PostgreSQL, с которым чаще всего работают Go-сервисы:
- время создания
created_at: событиям, логам и заказам подходит секционирование по диапазону, партиция на месяц или неделю. Значение не меняется, запросы почти всегда ограничены периодом, а старые данные удаляются черезDETACH PARTITIONиDROP TABLEвместо медленногоDELETE; - идентификатор владельца
tenant_idилиuser_id: для мультитенантных данных секционирование по хэшу даёт равномерное распределение, а запросы одного клиента попадают в одну партицию; - список значений
regionилиcountry: подходит, когда значений мало и они стабильны.
Выигрыш даёт partition pruning: планировщик отбрасывает лишние партиции, только если условие по ключу есть в WHERE. Проверяется это через EXPLAIN. Поэтому в Go-коде ключ передаётся в каждый запрос явным параметром, например WHERE tenant_id = $1 AND id = $2 в pgx, а не восстанавливается потом. Учтите ограничение: первичный ключ и уникальные индексы обязаны включать ключ партиционирования, так что id сам по себе уникальным на всю таблицу не будет.
Почему неизменность так важна: при смене ключа PostgreSQL переносит строку в другую партицию, фактически делая удаление и вставку. Это дороже обычного обновления, а в шардированных системах означает перенос строки между серверами, и многие из них такое обновление просто запрещают.
Где спотыкаются
Предлагают ключ по статусу (status = 'active'). Статус меняется, и строки начинают переезжать между партициями.
Выбирают ключ, которого нет в типичных запросах. Тогда каждый запрос сканирует все партиции и работает медленнее, чем на одной таблице.
Путают партиционирование с шардированием и говорят только про распределение по серверам, не упоминая pruning и дешёвое удаление старых данных.