Если ваши условия являются иерархическими (как в вашем примере), вы можете использовать комбинированный индекс.СУБД имеют проблемы при работе с несколькими индексами одновременно.Хотя это возможно, и они пытаются извлечь максимальную выгоду из такой ситуации.
Это не меняет того факта, что вам следует пытаться иметь определенный индекс для определенного предложения where.Если несколько индексов WHERE можно объединить в один, вы освободите некоторое пространство и циклы ЦП.
Начнем с определения индекса для каждого WHERE:
index1 (race_type, recordable_type, active)
index2 (race_type, recordable_id, recordable_type, active)
index3 (user_id, race_type, recordable_id, recordable_type, active)
InВ общем, вы можете оптимизировать свой заказ, увеличив количество элементов.Количество элементов - это число возможных значений, которые столбец будет иметь в вашем наборе данных .В вашем примере active
является логическим значением.(Обратите внимание, что тот факт, что boolean
может иметь только два значения, на самом деле не важен. Это может быть int
, если вы знаете, что оно будет иметь только два значения: 0 и 1 ).
Низкая мощность вашего поля active
означает, что с помощью одного поиска мы можем исключить половину возможных записей (конечно, в зависимости от вашего набора данных).После этого шага ваш первый индекс будет выглядеть так:
index1 (active, race_type, recordable_type)
Помимо кардинальности, вам следует обратить внимание на любую логическую иерархию между полями.Не зная точно, что означают эти имена, я полагаю, что некоторые типы рас будут иметь свои записываемые .- Это не исключает возможности использования записываемого материала с более чем одним типом расы, но вы должны выбрать ордер, и это кажется более логичным.- Таким образом, мы будем использовать порядок race_type
, recordable_type
.
Теперь давайте взглянем на второй индекс.Вы ввели recordable_id
здесь.Не зная вашего набора данных, я могу с уверенностью предположить, что количество элементов recordable_id будет больше, чем значение recordable_type.Другими словами, будет больше идентификаторов, чем типов.Также я подозреваю иерархию между типом и идентификатором (пахнет как один ко многим).Итак, давайте поместим его после типа:
index2 (active, race_type, recordable_type, recordable_id)
Теперь пришло время обратить внимание на другой важный аспект.Индексы имеют свою стоимость на вашем жестком диске (в основном бесплатную) и циклы ЦП, когда изменяет вашей БД.Подмножество любого индекса можно использовать, начиная слева направо.index2
по существу содержит index1
, как и index1 + recordable_id
, так что вы можете просто избавиться от него и в итоге получить один.
Вдоль user_id
.В качестве поля идентификатора он предлагает большую мощность (много возможных значений), но учтите, что не является правилом , что «чем больше мощность, тем позже будет заполнено поле».Мы скорее использовали кардинальность в качестве маяка, чтобы помочь определить иерархические отношения между полями.(И размеры индекса сокращения).
Указывает ли user_id
на отдельного участника, данные которого мы рассматриваем (много-много возможностей)?Или клиент загрузил данные (очень мало возможностей)?Сложно сказать.Вы можете просто добавить его к нашему существующему index2
, и в итоге вы получите один индекс, который можно использовать во всех трех секриариях:
search_index (active, race_type, recordable_type, recordable_id, user_id)
... или он может стоить иметь второй индекс дляthis scanario ...
Ваш вопрос особенный, поскольку в предложении where вы используете только =
.Есть много других соображений, если у вас было что-то вроде AND (race_type = 1 OR race_type=8)
Не говоря уже о >
или <
.Также, если вы используете ORDER BY
, это может быть учтено в используемых вами индексах.