INDEX: индексы

Открыта

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, 12:10
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, 13:48
Comparator<String> lengthComparator = Comparator.comparingInt(String::length);
Андрей
Уровень 109
27 июня 2024, 05:57
"не стесняйся добавлять индексы на все случаи жизни" ну хз даже)
Dima Makarov
Уровень 42
17 июля 2023, 11:23
Что-то не понял, а зачем нам несколько индексов? Не ужели нельзя сделать одну колонку индексов (или использовать колонку ИД) и хранить порядок сортировки этих ид
Екатерина
Уровень 100
Expert
18 октября 2023, 04:00
Запросы могут быть разные, а соотвественно и сортировка Например у меня 3 млн постов, я хочу найти самые популярные за неделю - я буду использовать один индекс "popuplar" (сортировать по дате, лайкам и т.п.) а теперь представь мне нужно найти все посты моих друзей "friend_post" в этом приложении? - я буду искать уже по июзерам и потом уже дате и тп. Конечно, если запросы одиновые - то нет смысла создавать новый индекс. Но если запросы по структуре разные, то индексы твои в этой таблице будут разные
СтаниславРаботает в NeomaticExpert
19 марта 2024, 08:08
Привет. Добавлю ещё один малореалистичный, но хорошо объясняющий пример: Допустим, у тебя в таблице есть множество колонок и две из них это год и месяц создания записи. В какой-то момент ты понимаешь, что большинство обращений за получением данных к этой таблице использует в критериях эти два поля вместе (ГДЕ год = 2020 И месяц = 01). По этой причине может оказаться эффективным добавить составной индекс. Тогда обращения к этой таблице с использованием (составного) индекса в значительной мере (в зависимости от размера таблицы) может ускорится. Легко будет вывести, например, самую старую или самую новую запись (СУБД выберет первый или последний индекс). В случае отсутствия индекса ей приходилось бы по параметру год перебрать все записи, а потом по параметру месяц. Большинство СУБД используют бинарный поиск по индексам (как в лекции про деревья).
SchlechtGut
Уровень 51
10 июля 2023, 05:59
"Как бы мы сделали аналогичную задачу в Java? Мы бы сначала отсортировали коллекцию пользователей по level, а потом можно было бы очень быстро найти нужные записи с помощью бинарного поиска. Надеюсь, не нужно объяснять, что это такое?" Сортировка - это n * log n, т.е. получится медленнее чем обычный проход. Плохая аналогия
DanielCEO в BicycleInventionAcad
14 июля 2023, 01:46
Сортировка происходит только при инициализации индекса/добавлении новых/изменении старых элементов. И у нее сложность действительно n log n Но получение элемента методом бинарного поиска в уже отсортированном массиве имеет сложность log n, что значительно быстрее линейного алгоритма со сложностью n Таким образом, если новые записи добавляются/старые изменяются редко, а запросов значений много, смысл использовать индексы однозначно есть. Но пусть с этим базисники воюют, нам и без этого жить слишком весело)
Родион
Уровень 113
4 августа 2025, 14:11
стало интересно что такое BicycleInventionAcad, загуглил, нейронка выдала только про тебя живая легенда получается
Станислав Future
Уровень 39
21 апреля 2023, 11:41
не простят