У меня есть таблица:
CREATE TABLE `player_statistics` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`player_id` INT(11) NOT NULL,
`statistic_id` INT(11) NOT NULL,
`value` INT(11) NOT NULL,
PRIMARY KEY (`id`),
INDEX `statistic_player_value` (`statistic_id`, `player_id`, `value`)
)
Как видно, имеется индекс statistic_player_value
, который содержит в себе 3 колонки: statistic_id
, player_id
, value
.
Я тестирую индекс таким запросом:
explain SELECT *
FROM `player_statistics`
WHERE `statistic_id`=1 AND `player_id` =15
ORDER BY `value` desc
LIMIT 10;
Результат:
+------+-------------+-------------------+------+-----------------------------------------------+------------------------+---------+-------------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------------------+------+-----------------------------------------------+------------------------+---------+-------------+------+--------------------------+
| 1 | SIMPLE | player_statistics | ref | player_id,statistic_id,statistic_player_value | statistic_player_value | 8 | const,const | 1 | Using where; Using index |
+------+-------------+-------------------+------+-----------------------------------------------+------------------------+---------+-------------+------+--------------------------+
Как видно, key_len
равен 8, а это значит, что индекс не использовался полностью. Только player_id
и statistic_id
использовали индекс. Я ожидаю, что key_len
должен быть равен 12.
Например, такой запрос выдает key_len
12:
explain SELECT *
FROM `player_statistics`
WHERE `statistic_id`=1 AND player_id =15 AND `value` = 1
Так в чем проблема, почему order by тогда не использует индекс?
У вас срабатывает составной индекс, так как используете в запросе WHERE
с указанием полей
key_len даёт понять используется ли он весь или только какая-то часть
Так как у вас поля INTEGER, которым выделена память 4 байта в базе, и в WHERE вы используется два поля, то в вашем запросе получается 8 при фильтрации по двум полям.
Либо 4 байта - по одному полю.
!! Потому что была произведена фильтрация и мы видим, что использовалось не 12 байтов, а 8 байтов в вашем случае.
Составной индекс может содержать более одного столбца и до 16 столбцов, но их общая длина ограничена 900 байтами.
Оптимизатор запросов MySQL пытается придумать оптимальный план выполнения этого запроса.
Даю подробности: Предистория для скриншотов ниже:
USING WHERE — не означает, что индекс не используется. Это означает, что результат дополнительно проверяется на соблюдение условий. Наличие индекса при вытаскивании данных можно увидеть в столбце key.
Ситуация с единичными полями:
Вопрос: Почему складывается ощющение, что не работает INDEX при ORDER BY? ОТВЕТ dev.mysql.com
Искать на странице строку ORDER BY Execution Plan Information Available
Отвечаю кратко и заранее: Не встретили в Extra column текста Using filesort - значит всё ОК! Если не используется индекc - увидите Using filesort
Проверка на работу индексов: удалите индекс и сделайте тот же запрос с EXPLAIN и если rows станет на порядок больше, значит до этого индексы работали.
Часть инфы может не выводится с EXPLAIN из-за версии sql, или тип базы данных, или используемых запросов + сам решает оптимизатор, что показать, а что нет
Собрал образ на основании вот этого Dockerfile:https://githubcom/mysql/mysql-docker/tree/mysql-server/8
Ваша строка не может указывать на функциюМожно сделать например так:
Есть базовый класс Computer и производный класс Laptop:
У меня базовый класс с двумя виртуальными методами и два класса-наследникаВ функции main есть массив указателей на базовый класс, который может...