Mysql Explain показывает, что запрос использует индекс, когда он не должен соответствовать Mysql doc - PullRequest
0 голосов
/ 31 мая 2019

Я создал многостолбцовый индекс mysql для таблицы транзакций.Этот индекс использует 3 столбца, как описано в моей схеме rails:

  add_index "merchant_transactions", ["reference", "parent_ref", "kind"], name: "by_reference_parent_ref_kind", using: :btree

Теперь у меня есть запрос активной записи:

MerchantTransaction.where(reference: "2-9020", kind: "PLACE_BATCH")

, который в чистом sql дает:

"SELECT `merchant_transactions`.* FROM `merchant_transactions` WHERE `merchant_transactions`.`reference` = '2-9020' AND `merchant_transactions`.`kind` = 'PLACE_BATCH'"

Теперь из того, что я прочитал об индексации mysql и нескольких столбцов:

Если таблица имеет индекс из нескольких столбцов, любой крайний левый префикс индекса может использоваться оптимизатором для поиска строк,Например, если у вас есть индекс из трех столбцов (col1, col2, col3), у вас есть индексированные возможности поиска для (col1), (col1, col2) и (col1, col2, col3).Для получения дополнительной информации, см. Раздел 8.3.5 , «Индексы с несколькими столбцами».

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

Однако, когда я запускаю EXPLAIN для моего запроса MerchantTransaction.where(reference: "2-9020", kind: "PLACE_BATCH").explain в столбце key, я получаю by_reference_parent_ref_kind, а в столбце Extra у меня есть Using index condition, что, по-видимому, означает, что индекс фактически используется.

Как это возможно?

Ответы [ 2 ]

1 голос
/ 31 мая 2019

Он будет использовать индекс, так как у вас есть самый левый столбец, указанный в запросе (reference), т.е. регистр использования (col1) из документов.Другой столбец в условии (kind) не ищется в индексе.

0 голосов
/ 01 июня 2019

Дано

WHERE reference = '...' AND kind = '...'

и

INDEX(reference, parent, kind)

Оптимизатор может использовать индекс, но только часть reference.

С другой стороны, еслиединственные столбцы, упомянутые в запросе, это те три, тогда этот индекс «покрывает», поэтому у оптимизатора есть еще одна причина использовать этот индекс.

Пожалуйста, укажите EXPLAIN SELECT ....В столбце Key_len будет указано, что используется только reference.В столбце Extra Using index является подсказкой о том, что он "покрывает".

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

INDEX(reference, kind, parent)
...