Перейти к основному содержимому
Модуль 10 · Урок 3 из 439/57 в курсе~12 min
Уроки модуля (3/4)

Составные и частичные индексы

В предыдущих уроках мы рассмотрели использование индексов для линейных запросов СУБД (WHERE country = 'Italy'). А как насчет того, когда мы ищем на двух комбинированных фронтах?

Например, в реальной электронной коммерции нам может потребоваться найти заказы, принадлежащие определенному идентификатору клиента И, попадающие в заданный диапазон времени: WHERE customer_id = 90 AND placed_at >= '2025-01-01'.

Если у вас есть только базовый индекс customer_id, Postgres мгновенно найдет 50 заказов клиента, используя двоичное дерево, но затем ему придется перебирать все 50 из них вручную и последовательно, лениво фильтруя даты на глаз.

Композитные индексы

Мы можем указать СУБД упорядочивать файлы «аналитического словаря» не по одному ключевому измерению, а по нескольким.

SQL
CREATE INDEX idx_orders_customer_date ON orders(customer_id, placed_at);

«Составной» индекс очень важен для порядка своих параметров: здесь узлы B-дерева группируются и жестко классифицируются customer_id в блоке (наиболее разборчивом для разделения); внутри них находится поддерево, разветвляющееся с различными значениями времени placed_at в идеально отсортированном порядке.

Эта структура грубо уничтожает предложения WHERE с несколькими вложенными предикатами.

Частичные индексы (фильтрованные индексы)

Каждый индекс требует дискового пространства и ресурсов ЦП для потоков пользовательского ввода. Что, если электронная коммерция требует постоянной сортировки и поиска фильтра, но только для меньшинства записей? (Например: быстрый опрос проверки непрочитанных уведомлений.) Создание индекса «is_read» для всех 10 000 000 уведомлений невероятно утомительно, если «Непрочитанные» представляют только 5 из них.

SQL
CREATE INDEX idx_unread_notifs ON notifications(user_id)
  WHERE is_read = false; -- Questa aggiuntiva è l'"Indice Parziale"

База данных создаст молниеносное B-дерево, в котором будут храниться ключи быстрого доступа к БД ТОЛЬКО, если запись непрочитана! Диск полюбит индекс в 5 строк (3 байта) вместо индекса в 10 миллионов. Быстрые SELECT в полной мере выигрывают:

SELECT * FROM notifications WHERE user_id = 2 AND is_read = false;

Ваша очередь

Упражнение#sql.m10.l3.e1
Попыток: 0Загрузка…

Мы хотим оптимизировать поиск временных паролей/токенов сброса. Мы очень часто выполняем вызовы SELECT в поисках всех зарегистрированных клиентов из определенной страны и известного города.\nСоздайте составной индекс с именем «idx_cust_loc» для «клиентов». Сначала передайте поле «страна» (что является более эксклюзивным), а затем поле «город».

Загрузка редактора…
Показать подсказку

Синтаксис: CREATE INDEX name ON table(col1, col2);

Решение доступно после 3 попыток

Изучение условных (частичных) индексов

Упражнение#sql.m10.l3.e2
Попыток: 0Загрузка…

Оптимизируйте поиск пользователей для покупок: пользователи предварительно регистрируются, но нам нужно только перечислить их в хронологическом порядке регистрации (создать индекс «signed_up_on» в «клиентах»), но ОГРАНИЧЕНО ТОЛЬКО покупателями из точного полного строки «город»: «Милан».

Загрузка редактора…
Показать подсказку

Обычно он объявляется в целевом свойстве; в конце вы добавляете волшебное ключевое слово WHERE city = 'Milano'.

Решение доступно после 3 попыток