Расскажите про необычные задачи с SQL или базами данных
Что проверяют
Работали ли вы с базой глубже, чем «дёрнул запрос, получил строки». Слово «необычные» это приглашение показать, что вы знаете возможности СУБД и умеете читать план запроса. Для Go отдельно смотрят, как вы обращаетесь с database/sql: пул соединений, контексты, закрытие ресурсов.
Как отвечать
Выберите задачу, где решение нашлось не в коде сервиса, а в базе. Рабочие сюжеты:
- очередь заданий для нескольких воркеров через
SELECT ... FOR UPDATE SKIP LOCKED, чтобы задача не досталась двоим; - идемпотентная вставка через
INSERT ... ON CONFLICT DO UPDATEвместо отдельной проверки «есть ли такая строка»; - иерархия или граф через рекурсивный CTE;
- дедупликация и отчёты через оконные функции вместо выгрузки всего в память сервиса;
- массовая загрузка через
COPY(в pgx этоCopyFrom), а не миллион одиночных вставок; - транзакционный outbox, чтобы запись в базу и отправка события не разъезжались;
- один активный планировщик на несколько реплик через advisory lock.
Обязательно скажите, чем проверяли: EXPLAIN (ANALYZE, BUFFERS) до и после, какой индекс добавили и почему именно такой, составной, частичный или по выражению. В части Go добавьте про SetMaxOpenConns и SetConnMaxLifetime, про контекст с таймаутом в каждом запросе и про то, что rows надо закрывать и проверять rows.Err().
Где спотыкаются
Рассказывают про оптимизацию общими словами: «переписал подзапросы на соединения, стало быстрее». Без плана запроса это гадание, планировщик часто разворачивает подзапрос сам, а выигрыш обычно даёт индекс или другой порядок соединения.
Забывают, что sql.DB это пул, а не соединение. Отсюда либо новый пул на каждый запрос, либо настройки по умолчанию и упор в лимит соединений базы, либо утечка на незакрытых rows.
Подают нормализацию как способ ускорить систему. Нормализация про целостность данных, а для отчётов она обычно добавляет соединений. Ускоряют индексы, предварительные агрегаты и денормализация под конкретный запрос.