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

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

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

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

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

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

Индексация в базах данных: какие данные плохо подходят для индексов

В контексте реляционных баз данных (MySQL, PostgreSQL и др.) индексы — это структуры данных, ускоряющие поиск и сортировку записей. Однако не все типы данных или столбцы эффективно индексируются. Вот основные категории данных, к которым нецелесообразно или нельзя присвоить индекс, либо индексирование будет малоэффективным.

1. Данные с очень низкой селективностью (кардинальностью)

Столбцы, где подавляющее большинство значений одинаковы, плохо подходят для индексации. Индекс на таком столбце почти не фильтрует данные, и СУБД часто игнорирует его, выполняя полное сканирование таблицы.

-- Пример: столбец "gender" со значениями 'M'/'F'
CREATE INDEX idx_gender ON users(gender); -- Неэффективно!

Почему: Если 90% записей имеют значение 'M', индекс не сузит выборку значительно. Оптимизатор может посчитать полное сканирование таблицы дешевле.

2. Столбцы с частыми операциями записи (INSERT/UPDATE/DELETE)

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

  • Логические флаги (например, is_active).
  • Счетчики или поля, часто обновляемые в реальном времени.
-- Пример: счетчик просмотров статьи
CREATE INDEX idx_views ON articles(view_count); -- Замедлит частые UPDATE

3. Большие объекты (BLOB, TEXT, JSON без ограничений)

Индексирование полей с очень большими значениями технически возможно (например, через префиксные индексы), но часто неэффективно из-за размера.

-- Пример: индексирование всего текстового поля
CREATE INDEX idx_content ON posts(content(1000)); -- Может быть тяжеловесным

Почему: Индекс будет занимать много памяти/диска, а сравнение длинных строк затратно. Для полнотекстового поиска лучше использовать специализированные полнотекстовые индексы.

4. Вычисляемые или производные данные (без сохранения)

Прямое индексирование выражений или функций в запросах невозможно без создания вычисляемого (виртуального) столбца с индексом.

-- НЕЛЬЗЯ так:
CREATE INDEX idx_year ON orders(YEAR(order_date)); -- Ошибка!

-- А так можно (создав виртуальный столбец):
ALTER TABLE orders ADD COLUMN order_year INT AS (YEAR(order_date)) STORED;
CREATE INDEX idx_order_year ON orders(order_year);

5. Данные, к которым редко обращаются в WHERE/JOIN/ORDER BY

Индекс, который никогда не используется в условиях запросов, бесполезен и только замедляет модификацию данных и занимает место.

6. Поля с нерегулярным распределением данных

Например, столбцы с хаотичными хэш-значениями (например, UUID версии 4) могут быть индексированы, но это приводит к фрагментации индекса из-за случайности, что снижает производительность.

CREATE INDEX idx_uuid ON devices(device_uuid); -- Может фрагментироваться

7. Отдельные элементы в составе составного индекса

Если у вас есть составной индекс (A, B, C), то:

  • Индекс на столбец C отдельно будет бесполезен для условий WHERE C = ... (если не используются A, B).
  • Однако некоторые СУБД (например, PostgreSQL) могут использовать сканирование только по индексу (index-only scan) в отдельных случаях.

Технические ограничения и исключения

  • В MySQL полнотекстовые индексы возможны только для TEXT/CHAR/VARCHAR и только в движках MyISAM/InnoDB.
  • В некоторых СУБД нельзя создать индекс по выражению без генерации виртуального столбца.
  • Пространственные данные (GIS) требуют специальных индексов (R-дерево).

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

Перед созданием индекса анализируйте:

  • Селективность данных (уникальность значений).
  • Частоту использования столбца в условиях запросов.
  • Соотношение операций чтения/записи.

Пример анализа селективности в MySQL:

-- Узнаем уникальность значений в столбце
SELECT 
    COUNT(DISTINCT status) / COUNT(*) AS selectivity
FROM orders;
-- Если результат < 0.1 (10%), индекс, вероятно, бесполезен.

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

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