Какие основные типы индексов существуют в реляционных базах данных (SQL) и для чего они используются?

«Какие основные типы индексов существуют в реляционных базах данных (SQL) и для чего они используются?» — вопрос из категории Базы данных и SQL, который задают на 10% собеседований QA Тестировщик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Индексы — это структуры данных, ускоряющие поиск и сортировку. Выбор типа зависит от структуры данных и видов запросов.

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

  1. B-дерево (B-tree): Стандартный и самый распространенный индекс. Подходит для большинства операций: равенство (=), диапазоны (BETWEEN, >, <), сортировка (ORDER BY).

    -- Создание B-tree индекса (по умолчанию в PostgreSQL и многих других СУБД)
    CREATE INDEX idx_users_email ON users(email);
    -- Ускоряет запросы типа: SELECT * FROM users WHERE email = 'user@example.com';
  2. Хеш-индекс (Hash): Обеспечивает сверхбыстрый поиск по точному совпадению (=). Не поддерживает поиск по диапазонам или операции сортировки.

    -- Создание хеш-индекса (PostgreSQL)
    CREATE INDEX idx_users_id_hash ON users USING HASH(id);
  3. GIN (Generalized Inverted Index): Оптимизирован для сложных, составных данных, где один столбец содержит множество значений.

    • Для чего: Полнотекстовый поиск, массивы (@>), JSONB-поля (?).
      -- Индекс для поиска по тегам в массиве
      CREATE INDEX idx_posts_tags ON posts USING GIN(tags);
      -- Ускоряет: SELECT * FROM posts WHERE tags @> ARRAY['python'];
  4. GiST (Generalized Search Tree): Универсальная структура, поддерживающая специфичные типы данных и поиска.

    • Для чего: Геопространственные данные (PostGIS), полнотекстовый поиск, поиск по интервалам.
      -- Индекс для геоданных
      CREATE INDEX idx_shops_location ON shops USING GiST(location);
      -- Ускоряет: SELECT * FROM shops WHERE location <-> point(37.6, 55.7) < 1000;
  5. BRIN (Block Range INdex): Эффективен для очень больших таблиц, где данные физически упорядочены на диске (например, по временной метке created_at). Занимает мало места, но менее точен, чем B-tree.

    -- Индекс для логов по дате
    CREATE INDEX idx_logs_created ON logs USING BRIN(created_at);

Важно помнить: Индексы ускоряют операции SELECT, но замедляют INSERT, UPDATE и DELETE, так как сама индексная структура также требует обновления. Создавать индексы нужно обдуманно, на основе анализа частых и медленных запросов.