Mysql не использует индекс при выборе неиндексированного поля - PullRequest
0 голосов
/ 02 марта 2019

У меня есть таблица meta со следующей структурой (это просто пример денормализованных данных)

`id` int(3) not null auto_increment primary key,
`category_id` int(3),
`subdomain` varchar(191),
`created_at` timestamp,
`updated_at` timestamp

Поле subdomain может хранить уникальные значения, и повторяющиеся значения, такие как 'general', могут бытьповторяется много раз

Ситуация 1

Также у меня есть индекс subdomain.Этот индекс применяется к запросу

Select `id` from `table` where `subdomain` = 'general'

Но когда я пытаюсь получить какое-то неиндексированное поле, mysql сканирует всю таблицу и индекс не используется

Select `created_at` from `table` where `subdomain` = 'general'

Как я знаю, Inno-Некластеризованный индекс БД хранит ссылку на строку, и нет необходимости выполнять линейный поиск по всем строкам для извлечения некоторого поля.

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

Независимо от того, сколько данных в таблице, результат всегда одинаков.

1 Ответ

0 голосов
/ 02 марта 2019

Это может произойти, когда фильтрация, поддерживаемая индексом, не очень избирательная / ваше значение для фильтрации имеет высокую мощность .Это означает, что большой процент ваших общих строк соответствует условию where, поддерживаемому индексом (например, 90% ваших строк соответствуют subdomain = 'general').Если вы используете индекс при этом условии, вы в конечном итоге обрабатываете больше данных по сравнению с полным сканированием таблицы.

Пример: у вас 100 строк, и 90 из них соответствуют subdomain = 'general'.

ПолноеДля сканирования таблицы необходимо получить доступ ко всем 100 строкам, чтобы проверить состояние и прочитать 90 значений для результата.

Для выбора с индексом необходимо получить доступ к 90 элементам в индексе, чтобы выполнить условие и следовать указателю из индекса.к фактической строке, чтобы выбрать неиндексированное значение из этой строки.Завершение 90 поисков по индексу + 90 чтений из строк = 180 операций.Это медленнее, чем полное сканирование таблицы, когда вы просто получаете доступ к некоторым строкам больше, чем нужно.Операции могут не иметь такой же стоимости, но в итоге вы будете выполнять больше работы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...