> Как использовать EXPLAIN и ANALYZE для оптимизации SQL запросов (Go)

Уровень: senior · Роль: backend · Категория: Технические вопросы

Компании: Т-Банк, Ютека

Стек: Go

> Пример ответа

EXPLAIN и ANALYZE - ключевые инструменты для анализа и оптимизации SQL-запросов в PostgreSQL (и других СУБД). В Go, при работе с драйверами вроде pgx или database/sql, их используют на этапе отладки, не в продакшене.

Как использовать:

  1. EXPLAIN - показывает план выполнения запроса без его фактического запуска. Выводит узлы (Seq Scan, Index Scan, Hash Join и т.д.) и их стоимость (cost). Стоимость - абстрактная единица, но чем она выше, тем медленнее запрос.

  2. EXPLAIN ANALYZE - выполняет запрос и возвращает реальное время выполнения, количество строк, число обращений к буферам. Это даёт точную картину узких мест.

Пример в Go (используя pgx):

GO
import (
"context"
"fmt"
"github.com/jackc/pgx/v5/pgxpool"
)
func analyzeQuery(pool *pgxpool.Pool, query string, args ...interface{}) {
ctx := context.Background()
// EXPLAIN ANALYZE с форматированием JSON для удобства парсинга
explainQuery := fmt.Sprintf("EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON) %s", query)
rows, err := pool.Query(ctx, explainQuery, args...)
if err != nil {
fmt.Println("Error:", err)
return
}
defer rows.Close()
for rows.Next() {
var plan string
if err := rows.Scan(&plan); err != nil {
fmt.Println("Scan error:", err)
return
}
fmt.Println(plan) // Вывод JSON-плана
}
}

Оптимизация на основе результатов:

  • Если видите Seq Scan на большой таблице - добавьте индекс.

  • Если Nested Loop с большим количеством строк - перепишите запрос или настройте work_mem.

  • Высокое значение Buffers: shared hit - данные в кэше, хорошо. Buffers: shared read - много дисковых операций, нужен индекс или увеличение shared_buffers.

Важно: ANALYZE модифицирует данные (для INSERT/UPDATE/DELETE), поэтому в Go используйте его только в тестовой среде или в транзакции с последующим ROLLBACK.

GO
tx, _ := pool.Begin(ctx)
defer tx.Rollback(ctx) // откат, чтобы не менять данные
tx.QueryRow(ctx, "EXPLAIN ANALYZE DELETE FROM users WHERE id = $1", 42).Scan(&plan)

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью