Зачем нужны составные индексы?

MySQL

что такое индекс

Чтобы понять индекс, нужно иметь в голове картинку, здесь рекомендуется представить кулинарную книгу, не обычную кулинарную, а увесистую кулинарную книгу на 5000 страниц с рецептами на разные случаи, блюда и времена года. Хотя этот рецепт является всеобъемлющим, у него есть недостаток, заключающийся в том, что он не по порядку, первая страница может быть баклажанами со вкусом рыбы, а 3000-я страница - тушеными баклажанами.

Неважно, ключевая проблема в том, что эта кулинарная книга не проиндексирована!

Вот первый вопрос, который вы должны задать себе: как найти кисло-сладкие свиные ребрышки в рецепте, если нет указателя?Единственный вариант - просмотреть его постранично, если он на странице 3892, то сколько страниц нужно Вы должны перевернуть, большинство Плохой случай в том, что это на последней странице, и вам придется перевернуть всю книгу.

Решение состоит в том, чтобы построить index.

Мы можем придумать несколько способов поиска, где имя рецепта может быть отправной точкой. Если вы создаете список по названию рецепта, за которым следует номер страницы, то вы индексируете книги по названию рецепта. Запись в нем может выглядеть так:

红烧排骨 : 45
猪肉饺子 : 320
酱萝卜 : 199

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

Но это нереально, и вам нужно искать рецепты на основе того, что есть в вашем холодильнике, например, или искать блюда на их основе. В этом случае вам нужно больше индексов.

Это создает вторую проблему, только одну, основанную на食谱名称Индекс, как я могу найти все рецепты, связанные с ребрышками? Не имея надлежащего указателя, вам все равно придется пройти всю кулинарную книгу - 5000 страниц. Это верно при поиске по ингредиентам или блюдам.

Для этого нам нужно построить еще один индекс, на этот раз индексирующий ингредиенты, в котором ингредиенты расположены в алфавитном порядке, где каждый ингредиент указывает на номер страницы всех рецептов, которые его содержат. базовый食材索引такое, что

牛肉 : 301, 342, 785, 2310, 2456, 4310 ...
山药 : 8, 20, 45, 78, 287, 1295, 4587 ...
猪肉 : 12, 124, 320, 890, 3719, ...

Это тот индекс, который вам нужен? Это полезно?

Если вам просто нужно знать список рецептов для данного ингредиента, этого указателя будет достаточно, но если вы также хотите включить любую другую информацию, связанную с рецептом, при поиске, вам нужно будет «сканировать» - как только вы узнаете номер страницы говядины, вы можете Перелистывая каждую страницу, найти название рецепта и определить тип блюда лучше, чем пролистать всю книгу, но этого недостаточно.

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

На самом деле это невозможно. Если вы начинаете с указателя названий рецептов, но не помните названий, поиск по указателю лишь немногим лучше, чем пролистывание всей книги. Начиная с ингредиентов, проверяется ряд номеров страниц, но эти номера страниц не могут быть вставлены в указатель на основе названия рецепта. Таким образом, в этом случае можно использовать только один индекс, индекс ингредиентов в этом случае более полезен.

Обычно считается, что в запросе должны быть найдены два поля, и для них могут быть разделены индексы. Существует готовый алгоритм: найдите номер страницы совпадения в каждом индексе и просканируйте пересечение их номеров страниц со списком, который соответствует обоим индексам. Это уменьшает общее количество сканирований. Некоторые базы данных реализуют этот алгоритм, но не в MongoDB. Даже если бы он был реализован, использование составного индекса для поиска двух полей всегда было бы более эффективным, чем алгоритм, который я только что описал. Помните, что база данных будет использовать только один индекс для каждого запроса. Если вы запрашиваете несколько полей, убедитесь, что у вас есть соответствующие индексы для этих полей.

так что мне теперь делать? К счастью, у нас есть составные индексы.

составной индекс

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

Составной индекс использует название ингредиента и рецепта по очереди и может быть помечен следующим образом: ингредиент-рецепт, часть которого выглядит следующим образом:

猪肉:
  猪肉白菜炖粉条: 320
  猪肉蛋卷: 3719
  猪肉脯: 890

鸡腿:
  红烧鸡腿: 82
  可乐鸡腿: 3710
  土豆焖鸡腿: 2578

西红柿
  西红柿炒鸡蛋: 4827
  西红柿鸡蛋汤: 2478
  西红柿牛腩: 489

Ценность этого индекса очевидна для людей, и теперь можно выполнять поиск по ингредиентам, чтобы приблизительно найти искомый рецепт, даже если вы помните только начало названия. Также ценно для машины, поскольку не нужно сканировать полное название рецепта для этого ингредиента.

Следует отметить, что порядок составного индекса очень специфичен. Предположим, что приведенный выше индекс перевернут на Recipe-Material. Может ли он заменить наш предыдущий индекс?

Очевидно, нет!С новым указателем, пока имя известно, поиск всегда будет находить рецепт, страницу в книге. Если вы ищете рецепт свинины с банановыми ингредиентами, можете быть уверены, что его не существует. После перелистывания мы должны знать название рецепта и искать ингредиенты, но реальность часто такова, что мы знаем ингредиенты, но не знаем названия рецепта.

Теперь есть три индекса для всей поваренной книги:食谱,食材а также食材-食谱, а это значит, что мы можем смело удалять индекс ингредиентов. Зачем? Поскольку указатель ингредиентов и рецептов может использоваться для индексации ингредиента, если вы знаете ингредиент, вы можете упростить составной указатель, чтобы получить список номеров страниц для рецептов, которые его содержат.

Суммировать

Эта статья представляет собой метафору для дальнейшего понимания индекса, из которой можно распознать некоторые простые эмпирические правила, а именно:

  1. Индексация может значительно сократить усилия, необходимые для получения документов. Без подходящего индекса единственный способ реализовать запрос — линейно просмотреть весь документ до тех пор, пока не будут выполнены условия запроса. Обычно это скан всей коллекции.
  2. При синтаксическом анализе запроса будет использоваться только индекс с одним ключом (или исключение), а для запросов, содержащих несколько ключей (таких как ингредиенты и рецепты), составной индекс, включающий эти ключи, может лучше анализировать запрос.

Например, в таблице учащихся есть индексы как по возрасту, так и по имени. Если вы запросите name="zhangsan" и age = 20, будет использоваться только один из индексов.

  1. Если есть указатель ингредиентов-рецептов, вы можете удалить указатель ингредиентов, и так и должно быть. Более абстрактно, если есть составной индекс a-b, то индекс только на a является избыточным. Но если b сам по себе является составным индексом (b=c-d), имеет смысл иметь и a-b, и a.
  2. Также важно соблюдать порядок ключей в индексе.