Индекс для нескольких столбцов в ActiveRecord - PullRequest
45 голосов
/ 26 июня 2009

В ActiveRecord есть два способа объявить индексы для нескольких столбцов:

add_index :classifications, [:species, :family, :trivial_names]
add_index :classifications, :species
add_index :classifications, :family
add_index :classifications, :trivial_names

Есть ли разница между первым подходом и вторым? Если да, то когда мне следует использовать первое, а когда второе?

Ответы [ 3 ]

89 голосов
/ 26 июня 2009

Вы сравниваете составной индекс с набором независимых индексов. Они просто разные.

Думайте об этом так: составной индекс дает вам быстрый поиск первого поля во вложенном наборе полей с последующим быстрым поиском второго поля ТОЛЬКО в записях, уже выбранных первым поле с последующим быстрым поиском третьего поля - опять же, только в записях, выбранных двумя предыдущими индексами.

Давайте возьмем пример. Ваш механизм базы данных сделает не более 20 шагов, чтобы найти уникальное значение в пределах 1 000 000 записей (если память служит) , если вы используете индекс. Это верно независимо от того, используете ли вы составной или независимый индекс, но ТОЛЬКО для первого поля («вид» в вашем примере, хотя я думаю, что вам понадобится семейство, вид и затем общее имя).

Теперь, скажем, есть 100 000 подходящих записей для этого первого значения поля. Если у вас есть только отдельные индексы, то любой поиск в этих записях займет 100 000 шагов: по одному для каждой записи, полученной по первому индексу. Это связано с тем, что второй индекс не будет использоваться (в большинстве баз данных - это немного упрощение) и должно использоваться грубое совпадение.

Если у вас есть составной индекс , тогда ваш поиск будет намного быстрее, потому что ваш поиск по второму полю будет иметь индекс в первом наборе значений. В этом случае вам понадобится не более 17 шагов, чтобы добраться до вашего первого соответствующего значения в поле 2 из 100 000 совпадений в поле 1 (журнал базы 2 из 100 000).

Итак: шаги, необходимые для поиска уникальной записи из базы данных из 1 000 000 записей с использованием составного индекса для 3 вложенных полей, где первое возвращает 100 000, а второе - 10 000 = 20 + 17 + 14 = 51 шагов.

Шаги, необходимые при одинаковых условиях только с независимыми индексами = 20 + 100 000 + 10 000 = 110 020 шагов.

Большая разница, а?

Теперь, не сходите с ума, ставя составные индексы повсюду. Во-первых, они дорогие по вставкам и обновлениям. Во-вторых, они используются только в том случае, если вы действительно выполняете поиск по вложенным данным (для другого примера я использую их при извлечении данных для имен входа для клиента за указанный диапазон дат). Кроме того, они не стоят того, если вы работаете с относительно небольшими наборами данных.

Наконец, проверьте документацию базы данных. В наши дни базы данных стали более изощренными в способности развертывать индексы, и сценарий «База данных 101», который я описал выше, может не подходить для некоторых (хотя я всегда развиваюсь так, как будто это происходит, поэтому я знаю, что получаю).

10 голосов
/ 26 июня 2009

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

Индексирование трех столбцов [A, B, C] хорошо работает, когда вам необходим доступ к значениям A, A + B и A + B + C. Это не будет хорошо, если ваш запрос (или условия поиска или что-то еще) не ссылается на A.

Когда A, B и C индексируются отдельно, некоторые оптимизаторы запросов к СУБД рассмотрят возможность объединения двух или более индексов (в зависимости от оценки эффективности оптимизатором) для получения аналогичного результата для одного индекса из нескольких столбцов.

Предположим, у вас есть система электронной коммерции. Вы хотите запросить заказы по purchase_date, customer_id и иногда обоим. Я бы начал с создания двух индексов: по одному для каждого атрибута.

С другой стороны, если вы всегда указываете purchase_date и customer_id, то один индекс для обоих столбцов, вероятно, будет наиболее эффективным. Порядок имеет большое значение: если вы также хотите запросить заказы на все даты для клиента, сделайте customer_id первым столбцом в индексе.

1 голос
/ 26 июня 2009

Из документов:

При создании индекса на нескольких столбцы, первый столбец используется как имя для индекса. Например, когда Вы указываете индекс по двум столбцам [: first,: last], СУБД создает индекс для обоих столбцов, а также Индекс для первого столбца: первый. Используя только имя для этого Индекс имеет смысл, потому что вы будете никогда не нужно создавать единый индекс с этим именем.

Используйте первый метод при создании составного индекса, а второй - при создании индексов для отдельных атрибутов.

Здесь есть несколько хороших моментов , когда использовать составные индексы , но суть в том, что они хороши при использовании оператора where для нескольких атрибутов. Обратите внимание, что они должны использоваться вместе с другими индексами (всегда индексируйте ваши внешние ключи), а не в качестве замены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...