Индексы — специальные структуры данных (чаще всего на основе B-деревьев), служащие для быстрого поиска данных по определённому столбцу или набору столбцов таблицы. Индексы ускоряют выборку, сортировку и фильтрацию, уменьшая количество просматриваемых строк.
Типы индексов:
Индексы ускоряют:
Могут замедлить:
Пример создания индекса:
CREATE INDEX idx_user_email ON users (email);
Пример, где индекс не помогает:
SELECT * FROM users WHERE lower(email) = 'test@example.com'; -- если индекс построен на email, но запрос использует функцию lower(email), индекс не используется!
Если добавить индекс ко всем столбцам таблицы, всегда ли ускорится выполнение всех SELECT-запросов?
Ответ:
Нет. Индексы ускоряют только те запросы, где фильтрация или сортировка происходит строго по индексированному столбцу без применения функций или операций, препятствующих использованию индекса. Чрезмерное количество индексов не только замедляет INSERT/UPDATE/DELETE, но и занимает много места, а некоторые сложные запросы могут и вовсе обходить индексы (например, при сканировании по диапазону с выражением).
Пример:
SELECT * FROM orders WHERE year(order_date) = 2023; -- если индекс только на order_date, индекс не работает из-за функции year()
История
В электронной почтовой системе был создан триггер, который создавал индекс для каждого часто используемого поля. Через полгода производительность системы упала — на каждую вставку или изменение строки тратилось в 4-5 раз больше времени. После аудита количество индексов сократили, система ускорилась.
История
В рекламной платформе часто встречались запросы SELECT с фильтром по
substring(url, 1, 10). Несмотря на индекс по url, SQL не задействовал индекс из-за функции substring. Решением стало введение отдельного поля для такой выборки и индекс по нему.
История
В программе лояльности был создан составной индекс на поля (customer_id, shop_id). При запросах только по shop_id индекс не применялся, и происходил полный скан таблицы (full scan). Это привело к утрате выгоды от индекса при расчетах бонусов. Помогла оптимизация: отдельный индекс по shop_id.