2016-03-09 3 views
2

Я провел несколько тестов с помощью INDEXES и их расположения размещения столбцов в запросе.Перемещение столбцов MySQL Optimizer

Допустим, у меня есть этот запрос:

EXPLAIN SELECT * FROM `languages` 
    WHERE 
     `languages`.`active` = 1 
     AND `languages`.`code` = 'nl_nl'; 

И 2 INDEXES:

  • code (UNIQUE)
  • active, code (имеет дело с ORDER BY)

EXPLAIN говорит, что возможно le - code,index__active__code, но, как ни странно, он выбрал code как ключевой.

Означает ли это, что оптимизатор запросов будет суетиться вокруг моих полей WHERE, чтобы они соответствовали одному или нескольким моим индексам лучше? Поэтому он сделает мой запрос:

SELECT * FROM `languages` 
WHERE 
    `languages`.`code` = 'nl_nl' 
    AND `languages`.`active` = 1 

?

Но тогда все же, почему он не решил получить индекс active, code? Это потому, что соответствующий тип равен const? Или UNIQUE всегда предпочитали?

Update:

Кроме того, это не имеет никакого смысла для меня:

EXPLAIN SELECT `id`, `property_id` FROM (`modeldimensions`) WHERE `model_id` = 11040 && `active` = 1; 

Возможных ключи: unique__model_id_property_id,index_model_id__active

Но пока он выбрал unique__model_id_property_id.

+0

'SHOW CREATE TABLE' - может быть некоторое взаимодействие с ПК. Могут быть некоторые проблемы с типами данных. И т. Д. –

ответ

2

Да, оптимизатор mysql рассмотрит все индексы, релевантные для запроса. Он собирается выбрать тот, который он считает наиболее эффективным, но он может ошибаться.

Mysql и большинство других rdbms рассматривают мощность (селективность) индекса как основного драйвера. Вы можете проверить всю мощность индекса в таблице information_schema.statistics или с помощью команды show index.

Кардинальность - это в основном число уникальных значений внутри индекса. Чем больше число мощностей, тем лучше индекс может использоваться для фильтрации записей.

К сожалению, мощность основана только на оценках и может быть неточной. Используйте команду analyse table, чтобы обновить мощность индекса, если он выключен.

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

+0

Да Я использую 'FORCE INDEX' в основном для MySQL, неспособного идентифицировать' ORDER BY', нужно использовать 'INDEX'. Знаете ли вы, что индексы 'UNIQUE' получают какое-то специальное лечение для оптимизатора? –

+0

Уникальные индексы должны иметь высокую мощность, поскольку они уникальны. Поэтому mysql должен быть более склонным использовать его. – Shadow

+0

Это имеет смысл, спасибо. Действительно, таблица для «modeldimensions» утверждает мощность 9030 на UNIQUE-ключах по сравнению с небольшим 184 на NON-UNIQUE. –

0

Оптимизатор видит, что (code) уникален, поэтому вам нужно будет посмотреть только на одну строку. Поскольку (active, code) не объявлен уникальным, оптимизатор предполагает, что ему может потребоваться несколько строк.

С другой стороны монеты это то, как индексы InnoDB индексируют. (Это таблица InnoDB?Пожалуйста, предоставьте SHOW CREATE TABLE, поэтому нам не нужно гадать.) Есть два вторичных ключей на выбор. (Это вторичные, правильные?) Казалось бы, выгоднее выбрать (active, code) в случае, если никакие строки не совпадают, и в этом случае не нужно было бы входить в данные для *. Но люди обычно не делают SELECT, чтобы ничего не получить, поэтому, возможно, это низкий приоритет.

EXPLAIN FORMAT=JSON SELECT ... может дать вам еще несколько подсказок «используемой модели затрат», поэтому он принял решение о «неправильном» индексе.