Подтвердить что ты не робот

Нужны два индекса в таблице соединения HABTM?

Простая ассоциация has_and_belongs_to_many:

Person has_and_belongs_to_many :products
Product has_and_belongs_to_many :persons

Являются ли обе следующих индексов полезными для оптимальной производительности?

add_index :person_products, [:person_id, :product_id]
add_index :person_products, [:product_id, :person_id]
4b9b3361

Ответ 1

Закрыть - вы, скорее всего, захотите следующее:

add_index :person_products, [:person_id, :product_id], :unique => true
add_index :person_products, :product_id

:unique => true строго не требуется, и это зависит от того, имеет ли смысл иметь человека, связанного с продуктом несколько раз. Я бы сказал, если вы не уверены, вероятно, вам нужен флаг :unique.

Причина структуры индекса заключается в том, что все современные базы данных могут выполнять запросы как для person_id, так и для product_id, используя первый индекс независимо от порядка, указанного в запросе. Например.

SELECT foo FROM bar WHERE person_id = 1 AND product_id = 2
SELECT foo FROM bar WHERE product_id = 2 AND person_id = 1

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

Аналогично, запросы, использующие только person_id, также могут быть запущены с использованием первого индекса. Многоколоночные индексы b-дерева могут использовать меньшее количество столбцов, чем они указывали слева от оригинальной декларации.

Для запросов, использующих только product_id, это не может быть выполнено против первого индекса (поскольку этот индекс определен с помощью person_id в крайнем левом положении). Следовательно, вам нужен отдельный индекс, чтобы включить поиск только в этом поле.

Многостолбцовое свойство индекса дерева b также распространяется на индексы с большим количеством столбцов. Если у вас есть индекс в (person_id, product_id, favorite_color, shirt_size), вы можете использовать этот индекс для запуска запросов с помощью person_id, (person_id, product_id) и т.д., Если порядок соответствует определению.

Ответ 2

Да, они полезны. Но вы действительно в них нуждаетесь? Все зависит от того, что вы собираетесь с этим делать. Индекс на (person_id,product_id) позволит вам быстро найти продукты, принадлежащие человеку, но не поможет найти людей, которые владеют определенным продуктом. Он также будет применять UNIQUE, поэтому вы, вероятно, должны его использовать. отдельные индексы на (person_id) и (product_id) позволят вам найти оба продукта, принадлежащие человеку и лицам, которые владеют определенным продуктом. Индексы на (person_id,product_id) и (product_id,person_id) будут работать и для обоих случаев, и будут быстрее, но будут занимать больше места, и при вставке/обновлении строк потребуется немного (очень немного). Накладные расходы времени и пространства почти всегда стоят того, если у вас нет базы, где вы пишете чаще, чем считаете. Лично я видел, что Index Only Scans в 9.2 значительно выигрывает от двух индексов в обоих столбцах. Итак, вы действительно решаете между:

unique index on (col 2, col 1), unique index on (col 1, col 2)

и

unique Index on (col 1, col 2), index on (col 2)

Ответ 3

Вам просто нужно, если вы не делаете unique

add_index :person_products, :person_id
add_index :person_products, :product_id

Или для индекса в обоих столбцах

add_index :person_products, [:person_id, :product_id]

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

http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/add_index