Индекс по created_at
Маленькая техническая заметка про SQL. Такая: если в таблице есть поле
created_at
, по нему должен быть btree-индекс. Если поля нет, его нужно
добавить вместе с индексом.
Объяснение следующее. Срез по времени – это самая частая задача в работе с данными. Если не фиксировать время события, это обернется бедой.
Эти два дня я отлаживал серьезный баг, о котором напишу отдельно. Но попутно выяснилось следующее. В базе данных есть таблица, которая фиксирует изменения сущностей. В ней один индекс – айди сущности. Это хорошо, если требуется расследовать конкретную сущность. Но оказалось, пострадало их много за определенный период, так что этот индекс бесполезен.
Я хотел выбрать события по времени, благо интервал небольшой, всего неделя. Но
оказалось, что у поля created_at
нет индекса. В таблице 400 миллионов записей,
и отбор по нему работает страшно медленно: limit 10
занимает 8 минут.
Добавить индекс в такую таблицу – страшно дорого. Это нужно делать ночью на выходных, кто на это пойдет?
Скажете: используй create index CONCURRENTLY
. А я скажу, что конкурентный
индекс не работает для партицированных таблиц, а наша именно такая. Нужно делать
либо обычный индекс в лоб, либо создавать конкурентный индекс для каждой
партиции. Все сложно.
По факту таблица превратилась в черную дыру: в нее все входит, но ничего не выходит. Она беспомощна из-за своей массы. Разве что можно найти данные по конкретной сущности, но этого часто недостаточно.
Время – ключевой фактор при расследовании инцидентов. Даже если в таблице миллиард записей, границы времени известны хотя бы примерно. Можно выбрать срез и дальше обработать его вручную. А если индекса нет, мы лишили себя такой возможности. Сами себе Буратины.
Поэтому – индекс по времени должен быть всегда и обязательно.
Нашли ошибку? Выделите мышкой и нажмите Ctrl/⌘+Enter