Приходилось ли работать с индексами и оптимизировать запросы?
Что проверяют
Насколько близко вы подходили к базе: правили ли реальные планы запросов или писали SQL и надеялись на лучшее. В Go нет тяжёлой ORM, которая прячет базу, поэтому спрашивают предметно. Следом уточняют: «как вы поняли, что нужен именно такой индекс».
Как отвечать
Ведите рассказ от симптома к замеру:
- поиск виновника:
pg_stat_statementsпоtotal_exec_time,auto_explainс порогом по длительности, время запроса из трассировки (otelpgxили свойpgx.QueryTracer); - разбор плана:
EXPLAIN (ANALYZE, BUFFERS)на данных, близких к боевым, сверка оценки строк с фактом; расхождение в разы это устаревшая статистика или коррелирующие условия; - выбор индекса: составной по правилу левого префикса (сначала равенство, затем диапазон и сортировка), частичный
WHERE is_activeпод горячую выборку, покрывающий сINCLUDEради index only scan, GIN дляjsonb; - выкатка:
CREATE INDEX CONCURRENTLYотдельной миграцией, обычныйCREATE INDEXдержит блокировку на запись.
Go-специфика отличает ответ от книжного: пул pgxpool с MaxConns под лимит базы, context с дедлайном плюс серверный statement_timeout, пакетная отправка через pgx.Batch и CopyFrom вместо цикла с QueryRow. Если перед базой стоит PgBouncer в режиме транзакций, скажите, почему в pgx пришлось менять режим выполнения запросов.
Цифры называйте честные: «900 мс на последовательном сканировании и 12 мс после составного индекса». Опыта не было: покажите ход мысли на конкретном запросе.
Где спотыкаются
Говорят про индексы только как про ускорение. Каждый индекс это лишняя работа на записи, потеря HOT-обновлений и место на диске. Сильный ответ включает обратную сторону: как искали неиспользуемые индексы через pg_stat_user_indexes.
Создают отдельный индекс на каждую колонку из WHERE и ждут, что планировщик их сложит. Один правильно упорядоченный составной почти всегда лучше трёх одиночных.
Меряют на пустой тестовой базе. На тысяче строк планировщик честно выбирает последовательное сканирование, и вывод «индекс не работает» берётся из ниоткуда. Туда же несовпадение типов параметра и колонки: индекс отключается, и видно это только в плане.