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

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

1.8 Middle🔥 191 комментариев
#Базы данных и SQL

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

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

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

Типы индексов в базе данных

Индексы — это критически важный инструмент для оптимизации производительности БД. За мою карьеру я видел, как неправильное использование индексов может убить приложение, но и правильные индексы спасают системы. Давайте разберёмся в типах.

1. B-Tree индекс

Мост распространённый и универсальный тип индекса. Используется по умолчанию в PostgreSQL, MySQL, Oracle.

// Создание B-Tree индекса на столбце
CREATE INDEX idx_users_email ON users(email);

// B-Tree структура позволяет эффективно искать:
// = (равенство)
// >, <, >=, <= (диапазоны)
// LIKE 'abc%' (префикс)
// ORDER BY, GROUP BY

Как работает: B-Tree сбалансированное дерево, где каждый узел содержит несколько значений. Поиск O(log n), что очень быстро даже на миллионах записей.

Когда использовать: Поиск по primary key, Foreign key relationships, WHERE условия с =, >, <, Сортировка ORDER BY, Группировка GROUP BY.

2. Hash индекс

Использует хеш-таблицу для быстрого поиска точных совпадений.

CREATE INDEX idx_user_uuid ON users USING HASH(user_id);

// Очень быстро для точных совпадений
SELECT * FROM users WHERE user_id = uuid_value;

Особенности: O(1) поиск для равенства (в идеале), не работает с диапазонами, не поддерживает сортировку.

3. Bitmap индекс

Основано на битовых массивах. Эффективно для данных с низкой кардинальностью.

CREATE BITMAP INDEX idx_users_is_active ON users(is_active);
CREATE BITMAP INDEX idx_orders_status ON orders(status);

Когда использовать: Булевы поля, Enum'ы с низкой кардинальностью, Data warehouse запросы.

4. Full-Text Search (FTS) индекс

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

CREATE INDEX idx_articles_content ON articles 
USING GIN(to_tsvector('english', content));

SELECT * FROM articles 
WHERE to_tsvector('english', content) @@ 
      plainto_tsquery('english', 'database optimization');

Возможности: Игнорирование стоп-слов, Stemming (поиск по корню слова), Ranking по релевантности.

5. Composite (Multi-column) индекс

Индекс на нескольких колонках. Порядок колонок КРИТИЧЕСКИ важен.

@Entity
@Table(name = "orders", indexes = {
    @Index(name = "idx_user_status_date", 
           columnList = "user_id,status,created_date")
})
public class Order {
    @Id private Long id;
    private Long userId;
    private String status;
    private LocalDateTime createdDate;
}

Правило LEFT-TO-RIGHT: Индекс эффективен только если используются его первые колонки. Если индекс (user_id, status, date), то запрос по status без user_id не использует индекс.

6. Partial (Conditional) индекс

Индекс только на подмножество данных.

CREATE INDEX idx_active_orders ON orders(user_id) 
WHERE status != 'CANCELLED';

CREATE INDEX idx_recent_logs ON logs(user_id, timestamp) 
WHERE created_date > CURRENT_DATE - INTERVAL '30 days';

7. JSONB индекс (PostgreSQL)

Для поиска внутри JSON данных.

CREATE INDEX idx_user_metadata ON users USING GIN(metadata);

SELECT * FROM users 
WHERE metadata->>'language' = 'Russian';

8. Expression (Function-based) индекс

Индекс по результату функции.

CREATE INDEX idx_users_email_lower ON users(LOWER(email));

SELECT * FROM users WHERE LOWER(email) = email_value;

Практические советы

Как выбрать индексы:

  1. Найти медленные запросы (EXPLAIN, query logs)
  2. Анализировать WHERE, JOIN, ORDER BY условия
  3. Создавать индексы на часто используемые колонки
  4. Использовать COMPOSITE индексы для multi-column WHERE
  5. Помнить про LEFT-TO-RIGHT правило

Когда НЕ нужны индексы:

  • Таблица содержит менее 5K записей
  • Колонка с очень высокой кардинальностью используется редко
  • Индекс медленнее полного сканирования

Мониторинг индексов:

-- Найти неиспользуемые индексы
SELECT schemaname, tablename, indexname, idx_scan 
FROM pg_stat_user_indexes 
WHERE idx_scan = 0
ORDER BY idx_blks_read DESC;

Правильные индексы — разница между приложением, работающим за миллисекунды, и тормозящим. Начинаю с профилирования, потом добавляю индексы на основе данных.