INDEX: индексы

Модуль 4. Работа с БД
6 уровень , 6 лекция
Открыта

7.1 Причины появление индексов

Еще одна важная вещь, без который не может быть баз данных — это индексы.

Представь себе ситуацию, когда в таблице user есть 10 миллионов пользователи, и тебе нужно вывести всех, у кого уровень выше 90. Этот запрос написать очень просто:


SELECT * FROM user WHERE level > 90
        

Отлично, мы написали запрос меньше чем за минуту. А сколько времени займет выполнение этого запроса у SQL-сервера? Для выполнения такого запроса ему придется пройти по 10 миллионам записей, и даже если искомая запись всего одна, то это займет кучу времени.

Как бы мы сделали аналогичную задачу в Java? Мы бы сначала отсортировали коллекцию пользователей по level, а потом можно было бы очень быстро найти нужные записи с помощью бинарного поиска. Надеюсь, не нужно объяснять, что это такое?

Отлично, а что делать, если теперь нам нужно отобрать пользователей, чья дата регистрации была до 2020 года? Опять сортировать по дате регистрации и использовать бинарный поиск.

Ага, если мы выполняем фильтр по какому-то полю, причем не один раз, а часто, то будет очень полезно хранить данные отсортированными по этому полю.

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

А ответ очень прост — нужно хранить не сами данные, а их индексы в некой глобальной таблице.

Допустим, есть 10 пользователей с id: {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}.

И ты решаешь отсортировать их по уровню, тогда массив их id будет, например, таким: {9, 2, 3, 1, 5, 4, 8, 6, 7, 10}.

А если отсортировать их по дате, то мы получим, например: {10, 1, 8, 7, 2, 3, 5, 9, 6}.

Массивы этих id и называются индексами. Сами элементы большие, их мы не трогаем. В Java мы не трогаем объекты, а храним их ссылки, в SQL мы не трогаем реальные строки, а храним их номера.

Давай я еще раз запишу это в виде Java-кода:


List<String> list = List.of("А", "С", "B", "Z", "Сc", "Bb", "Zz", "Y");  //это список объектов
List<String> alphabeticsList = new ArrayList(list);
Collections.sort(alphabeticsList); //коллекция отсортированная по алфавиту
 
List<String> lengthList = new ArrayList(list);
Collections.sort(lengthList, lengthComparator); //коллекция отсортированная по длине строк

Сортировка коллекций не означает перемещение реальных элементов. Коллекция хранит не реальные объекты, а ссылки на них. Так же и в таблицах SQL. Реальные строки лежат себе и лежат.

И когда нам нужно часто делать выборки по какому-то полю, то мы добавляем еще один индекс к таблице (аналог новой коллекции в Java) и сортируем строки таблицы, храним их отсортированный порядок в специальном файле индексов.

Надеюсь, сравнение с Java немного помогло. Немного практики — и для тебя использование индексов тоже станет самым очевидным решением.

7.2 Добавление индексов в таблицу

Индекс можно указать сразу во время создания таблицы или же добавить после. Чаще всего встречается именно второй сценарий – индексы добавляют по мере роста размеров таблицы и замедления выборки данных.

Добавить индекс в таблицу очень просто:


ALTER TABLE таблица
    ADD INDEX имя_индекса (колонка);
        

Если ты часто ищешь записи по нескольким колонкам одновременно, можешь указать составной индекс: для его составления SQL использует несколько колонок.

Добавить составной индекс в таблицу тоже очень просто:


ALTER TABLE таблица
    ADD INDEX имя_индекса (колонка1, колонка2, колонка3, ...);
        

Индексы занимают достаточно много места на диске, так что если какой-то индекс тебе больше не нужен, ты всегда можешь удалить его:


ALTER TABLE таблица
    DROP INDEX имя_индекса;
        

Сами индексы — это достаточно скрытая часть базы данных. Они никак не влияют на формат написания запросов. Просто их наличие ускоряет выборку данных и замедляет их добавление и бэкап.

Но учитывая, как важна скорость в современном мире и как дешево место на дисках, не стесняйся добавлять индексы на все случаи жизни. Да простят меня админы…

1
Задача
Модуль 4. Работа с БД, 6 уровень, 6 лекция
Недоступна
task0625
Напиши запрос, который создаст индекс population_index в таблице cities по колонке population.
1
Задача
Модуль 4. Работа с БД, 6 уровень, 6 лекция
Недоступна
task0626
Напиши запрос, который создаст индексы в таблице employee: position_index по колонке position и salary_index по колонке salary.
1
Задача
Модуль 4. Работа с БД, 6 уровень, 6 лекция
Недоступна
task0627
Напиши запрос, который удалит индекс salary_index из таблицы employee. Используй ALTER TABLE.
1
Задача
Модуль 4. Работа с БД, 6 уровень, 6 лекция
Недоступна
task0628
Напиши запрос, который удалит индексы name_index и salary_index из таблицы employee. Используй ALTER TABLE.
Комментарии (10)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
11 мая 2025

List<String> list = List.of("А", "С", "B", "Z", "Сc", "Bb", "Zz", "Y");  //это список объектов
List<String> alphabeticsList = new ArrayList(list);
Collections.sort(alphabeticsList); //коллекция отсортированная по алфавиту

List<String> lengthList = new ArrayList(list);
Collections.sort(lengthList, lengthComparator); //коллекция отсортированная по длине строк
а где lengthComparator в коде создан?
Zim4ik Уровень 51
5 ноября 2025
Comparator<String> lengthComparator = Comparator.comparingInt(String::length);
Андрей Уровень 109
27 июня 2024
"не стесняйся добавлять индексы на все случаи жизни" ну хз даже)
Dima Makarov Уровень 42
17 июля 2023
Что-то не понял, а зачем нам несколько индексов? Не ужели нельзя сделать одну колонку индексов (или использовать колонку ИД) и хранить порядок сортировки этих ид
Екатерина Уровень 100 Expert
18 октября 2023
Запросы могут быть разные, а соотвественно и сортировка Например у меня 3 млн постов, я хочу найти самые популярные за неделю - я буду использовать один индекс "popuplar" (сортировать по дате, лайкам и т.п.) а теперь представь мне нужно найти все посты моих друзей "friend_post" в этом приложении? - я буду искать уже по июзерам и потом уже дате и тп. Конечно, если запросы одиновые - то нет смысла создавать новый индекс. Но если запросы по структуре разные, то индексы твои в этой таблице будут разные
Станислав Уровень 83 Expert
19 марта 2024
Привет. Добавлю ещё один малореалистичный, но хорошо объясняющий пример: Допустим, у тебя в таблице есть множество колонок и две из них это год и месяц создания записи. В какой-то момент ты понимаешь, что большинство обращений за получением данных к этой таблице использует в критериях эти два поля вместе (ГДЕ год = 2020 И месяц = 01). По этой причине может оказаться эффективным добавить составной индекс. Тогда обращения к этой таблице с использованием (составного) индекса в значительной мере (в зависимости от размера таблицы) может ускорится. Легко будет вывести, например, самую старую или самую новую запись (СУБД выберет первый или последний индекс). В случае отсутствия индекса ей приходилось бы по параметру год перебрать все записи, а потом по параметру месяц. Большинство СУБД используют бинарный поиск по индексам (как в лекции про деревья).
SchlechtGut Уровень 51
10 июля 2023
"Как бы мы сделали аналогичную задачу в Java? Мы бы сначала отсортировали коллекцию пользователей по level, а потом можно было бы очень быстро найти нужные записи с помощью бинарного поиска. Надеюсь, не нужно объяснять, что это такое?" Сортировка - это n * log n, т.е. получится медленнее чем обычный проход. Плохая аналогия
Daniel Уровень 51
14 июля 2023
Сортировка происходит только при инициализации индекса/добавлении новых/изменении старых элементов. И у нее сложность действительно n log n Но получение элемента методом бинарного поиска в уже отсортированном массиве имеет сложность log n, что значительно быстрее линейного алгоритма со сложностью n Таким образом, если новые записи добавляются/старые изменяются редко, а запросов значений много, смысл использовать индексы однозначно есть. Но пусть с этим базисники воюют, нам и без этого жить слишком весело)
Родион Уровень 113
4 августа 2025
стало интересно что такое BicycleInventionAcad, загуглил, нейронка выдала только про тебя живая легенда получается
Станислав Future Уровень 39
21 апреля 2023
не простят