← Назад к вопросам

Какие использовал типы индексов?

2.3 Middle🔥 183 комментариев
#Базы данных#Производительность и оптимизация

Комментарии (3)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Типы индексов в SQL-базах данных: анализ практического опыта

Как разработчик с фокусом на Go и взаимодействием с базами данных, я использовал и настраивал различные типы индексов для оптимизации запросов, обеспечения целостности данных и поддержки специфических сценариев доступа.

Основные типы индексов

1. B-дерево (B-Tree) — стандартный и наиболее распространённый индекс Это индекс по умолчанию в PostgreSQL, MySQL и многих других СУБД. Он эффективен для операций сравнения (=, >, <, BETWEEN), сортировки (ORDER BY) и поиска по префиксу.

-- Пример создания B-Tree индекса в PostgreSQL
CREATE INDEX idx_users_email ON users(email);
-- Эффективен для: WHERE email = 'test@example.com'

2. Хеш-индекс (Hash Index) Используется только для операций равенства (=). Внутренне хранит хеш-код значения, что обеспечивает сверхбыстрый поиск точных совпадений, но не поддерживает диапазонные запросы или сортировку.

-- В PostgreSQL hash требует отдельного указания
CREATE INDEX idx_users_id_hash ON users USING HASH(id);
-- Эффективен для: WHERE id = 12345

3. Составной (композитный) индекс Индекс по нескольким столбцам. Порядок столбцов критически важен — запрос должен использовать префикс индекса. Например, индекс (last_name, first_name) будет работать для поиска по last_name, но не для first_name отдельно.

CREATE INDEX idx_users_name ON users(last_name, first_name);
-- Работает: WHERE last_name = 'Ivanov' AND first_name = 'Alexey'
-- Не работает: WHERE first_name = 'Alexey'

4. Частичный индекс (Partial/Filtered Index) Индекс, построенный на подмножестве строк таблицы, что экономит дисковое пространство и ускоряет операции за счёт меньшего размера индекса.

-- Индекс только для активных пользователей
CREATE INDEX idx_users_active ON users(id) WHERE is_active = true;

5. Уникальный индекс (Unique Index) Гарантирует уникальность значений в столбце или комбинации столбцов. Часто используется для primary key или полей типа email.

CREATE UNIQUE INDEX idx_unique_email ON users(email);

Специализированные типы индексов

6. Полнотекстовый индекс (Full-Text Search Index) Оптимизирован для текстового поиска с учётом морфологии, стоп-слов и ранжирования. Использует структуры типа GIN (Generalized Inverted Index) в PostgreSQL или специальные движки в MySQL (InnoDB FTS).

// Пример использования в Go с PostgreSQL и библиотекой pgvector или plain text search
query := `SELECT * FROM articles 
           WHERE to_tsvector('russian', content) @@ to_tsquery('russian', $1)`
rows, err := db.Query(query, "Go & база данных")

7. Индексы для пространственных данных (GIST, SP-GIST) Для работы с геоданными (PostgreSQL с PostGIS). Использует GIST (Generalized Search Tree) для многомерных данных — точки, полигоны, расстояния.

CREATE INDEX idx_locations_geo ON locations USING GIST(coordinates);

8. BRIN (Block Range Index) Эффективен для очень больших таблиц с естественной сортировкой данных (например, временные ряды). Работает с диапазонами блоков хранилища, имеет малый размер.

CREATE INDEX idx_logs_created_at ON logs USING BRIN(created_at);

Анализ производительности и паттерны использования в Go

В контексте Go-разработки, важно не только создавать индексы, но и анализировать их использование через EXPLAIN ANALYZE, контролировать влияние на запись (индексы замедляют INSERT/UPDATE/DELETE) и использовать мониторинг.

// Практический пример: выбор индекса для полисов в страховой системе
func createPolicyIndexes(db *sql.DB) error {
    // B-Tree для поиска по номеру полиса (уникальный)
    _, err := db.Exec(`CREATE UNIQUE INDEX idx_policies_number ON policies(policy_number)`)
    if err != nil {
        return fmt.Errorf("failed to create unique index: %w", err)
    }
    
    // Составной индекс для частых запросов по статусу и дате
    _, err = db.Exec(`CREATE INDEX idx_policies_status_date ON policies(status, created_at)`)
    return err
}

Ключевые принципы, которые я применяю:

  • Индексирую высокоселективные столбцы (с большим количеством уникальных значений).
  • Избегаю избыточных индексов — например, если есть индекс (A, B), то индекс (A) часто не нужен.
  • Для JSONB в PostgreSQL использую GIN-индексы для работы с вложенными структурами.
  • Регулярно перестраиваю индексы в высоконагруженных системах для борьбы с фрагментацией.

Выбор типа индекса — это всегда компромисс между скоростью чтения, скоростью записи, потреблением памяти и дискового пространства. В Go-приложениях этот выбор напрямую влияет на задержки ответа API и общую производительность системы.

Какие использовал типы индексов? | PrepBro