MySQL. Создание индекса для запросов "ИЛИ"
У меня есть таблица из 200 тыс. записей с столбцами INT. Я хочу создать индекс, чтобы делать запросы быстрее. Это запрос, который я хотел бы выполнить: SELECT A,B,C,D,E FROM table WHERE A=23 and (B=45 or C=43)
. Я создал следующие индексы: B
, ACD
, C
, ABC
.
С помощью команды EXPLAIN
я обнаружил, что MySQL выбирает индекс ACD
. Поэтому я продолжал заполнять таблицу большим количеством значений, и я понял, что MySQL переключался между указанными выше индексами (не всегда один и тот же).
Так как существует много вложений, наличие различных индексов вызовет проблемы с производительностью, и мы можем предположить, что к этой таблице обращаются другие запросы, для которых требуются разные столбцы, где каждый индекс имеет смысл.
Мне известно о USE INDEX()
, но я хотел бы понять, следует ли нам доверять MySQL, чтобы выбрать правильный индекс.
Ответы
Ответ 1
Из-за OR
в инструкции SQL MySQL просто получает первый индекс, включающий A
, который равен ACD
.
Я пришел к выводу, что способ решить эту проблему с помощью INDEX
состоит в том, чтобы сделать два отдельных запроса. SELECT A,B,C,D,E FROM table WHERE A=23 AND B=45
, который будет использовать INDEX ABC
, а затем SELECT A,B,C,D,E FROM table WHERE A=23 AND C=43
, который будет использовать INDEX ACD
. Все это можно сделать за один шаг с помощью (...) UNION (...)
, который оказывается более быстрым и использует только INDEX.
Ответ 2
Mysql может использовать только "левую часть" составного индекса. То есть, если ваше предложение where выглядит как
WHERE A=1 AND B=2
тогда MySQL может использовать индекс на A
или AB
, но лучше всего будет AB
. ACB
не может использоваться, поскольку индекс разбивается на другой столбец
С вашим заданным предложением WHERE я не думаю, что механизм запросов MySQL может использовать несколько индексов. Я бы сделал AB
и AC
и используя FORCE INDEX, посмотрите, какой из них быстрее.
Совокупный ключ из трех столбцов в этом случае не поможет, поскольку вы смотрите на A и другой столбец. Этот ключ поможет, если ваш запрос использовал AND
вместо OR
. Индекс на ABC
был бы полезен для
WHERE A=1 AND B=2 AND C=3