Как выбрать подходящий индекс для таблицы в реляционной базе данных?

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

Ответ

Выбор индекса основывается на анализе запросов и данных. Основные критерии:

1. Частота и тип запросов:

  • Индексируйте поля, используемые в условиях WHERE, JOIN, ORDER BY и GROUP BY.
  • Для запросов с диапазоном (BETWEEN, >, <) используйте B-деревья.
  • Для точного совпадения (=) или проверки наличия (IN) подходят хэш-индексы.

2. Селективность (кардинальность):

  • Высокая селективность (уникальные или почти уникальные значения) — идеальна для индексации. Используйте UNIQUE индекс.
  • Низкая селективность (мало уникальных значений, например, пол или статус) — индекс менее эффективен. В некоторых СУБД (Oracle) можно рассмотреть BITMAP индекс.

3. Составные (композитные) индексы:

  • Порядок столбцов критически важен из-за правила левого префикса. Первым должен идти столбец с самой высокой селективностью.
  • Пример для частого запроса WHERE user_id = ? AND status = ? AND created_at > ?:
    -- Оптимальный порядок: user_id (высокая селективность), затем status, затем created_at
    CREATE INDEX idx_user_status_date ON orders(user_id, status, created_at);

4. Практические рекомендации и инструменты:

  • Избегайте избыточности: Не создавайте индексы, которые дублируются или покрываются другими индексами.
  • Анализируйте планы выполнения: Используйте EXPLAIN (или EXPLAIN ANALYZE) для оценки влияния индекса на конкретный запрос.
  • Мониторьте влияние на запись: Индексы замедляют операции INSERT, UPDATE, DELETE. Балансируйте между скоростью чтения и записи.
  • В ORM (например, JPA/Hibernate): индексы можно задавать через аннотации.
    @Entity
    @Table(name = "orders", indexes = {
        @Index(name = "idx_user_status", columnList = "user_id, status")
    })
    public class Order {
        // ...
    }