Что делать, если таблица постов разрослась и замедлилась
Что проверяют
Пойдёте ли вы от измерения или начнёте перечислять приёмы оптимизации подряд. Для бэкенда на Python отдельно смотрят, видите ли вы, что часть проблем создаёт не база, а код приложения поверх неё.
Как отвечать
Сначала выясните, что именно медленно. Общего «таблица тормозит» не бывает, есть конкретные запросы. Включите логирование долгих запросов, посмотрите накопленную статистику по суммарному времени, снимите план виновника через EXPLAIN (ANALYZE, BUFFERS) и сравните оценку с фактом.
Дальше по слоям. Со стороны приложения на большом объёме первыми всплывают:
- пагинация через
OFFSET, которая с ростом номера страницы перечитывает всё до неё. Лечится переходом на ключ:where (created_at, id) < (:ts, :id) order by created_at desc, id desc limit 20; - подсчёт общего числа строк ради номеров страниц. На большой таблице это отдельный тяжёлый запрос, часто хватает приблизительной оценки или выдачи без общего числа;
- запрос на каждый элемент выдачи из ORM: авторы, теги и счётчики тянутся по одному, и страница делает сотни обращений;
- выборка всех колонок, включая длинный текст поста, когда в списке нужны заголовок и дата.
Со стороны базы: индексы под фактические сочетания фильтра и сортировки, частичный индекс под условие видимости, свежая статистика. Если объём продолжает расти, переходите к нарезке по времени и переносу старых постов в архивную таблицу.
Где спотыкаются
Вешают индекс на каждую колонку из условий. Запись замедляется, место растёт, а планировщик всё равно берёт один подходящий.
Второе: строят индекс на боевой таблице обычной командой и держат блокировку на запись. Для больших таблиц есть построение без блокировки, и делать это стоит в часы низкой нагрузки.
Третье: путают нарезку одной таблицы на части внутри базы и разнесение данных по разным серверам. Первое делается штатными средствами, второе меняет архитектуру приложения целиком.