Какие знаешь типы индексов в базе данных?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Типы индексов в базе данных
Индексы — это критически важный инструмент для оптимизации производительности БД. За мою карьеру я видел, как неправильное использование индексов может убить приложение, но и правильные индексы спасают системы. Давайте разберёмся в типах.
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;
Практические советы
Как выбрать индексы:
- Найти медленные запросы (EXPLAIN, query logs)
- Анализировать WHERE, JOIN, ORDER BY условия
- Создавать индексы на часто используемые колонки
- Использовать COMPOSITE индексы для multi-column WHERE
- Помнить про 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;
Правильные индексы — разница между приложением, работающим за миллисекунды, и тормозящим. Начинаю с профилирования, потом добавляю индексы на основе данных.