У меня есть MySQL таблица «user» со (среди прочего) столбцами «name1» и «name2» (имя / фамилия) и ~ 100K строк. Каждый из этих столбцов имеет свой собственный регулярный индекс, и EXPLAIN распознает эти индексы. Теперь я выполняю очень простой запрос:
SELECT * FROM user WHERE name1 LIKE '%something%' ORDER BY name1 LIMIT 100
Этот запрос занимает 25 секунд на сервере с MySQL 8.0.19 (то же самое с "name2"). Но если я опущу ORDER BY или LIMIT (или оба), это займет всего 0,5 секунды. В любом случае он возвращает пустой набор (но если я использую другую строку, которая генерирует реальные результаты, время не влияет, поэтому это не имеет значения). Хорошо, я понимаю, что без ORDER BY или LIMIT это должно быть быстрее, но MySQL должен справиться с этим. Действительно, когда я выполняю тот же запрос на MySQL 5.6 (на другом сервере, но с аналогичным оборудованием), это занимает 0,5 секунды. Но вот самая странная часть. Теперь я запускаю следующий запрос:
SELECT * FROM user WHERE name1 LIKE '%something%' ORDER BY name1,name2 LIMIT 100
Единственное изменение состоит в том, что я также добавил упорядочивание по "name2". Должно быть еще сложнее в теории, но теперь это занимает 0,5 секунды вместо 25! И нет, нет никакого взаимного индекса для name1 и name2 или чего-либо еще. Я не думаю, что это общая проблема с сервером - MySQL явно пересекает все строки вместо использования индекса (хотя EXPLAIN утверждает, что использует индексы).
Итак, мои вопросы: - Были ли у вас когда-либо видела такую проблему при обновлении до 8.0 (некоторые запросы неожиданно становятся медленнее на порядки, а другие работают так же быстро)? - Что может быть причиной такой плохой работы? Может быть, что добавление еще одного столбца сортировки делает запрос в 50 раз быстрее? Это ускорение на самом деле происходит и в 5.6 (с 0.5 se c до 0.07 se c, так что, возможно, это не сбой только в 8.0). - Может ли это быть просто ошибкой или недостатком дизайна в MySQL 8.0?
ОБНОВЛЕНИЕ 1:
Для первого запроса выше EXPLAIN выдает следующее:
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE candidate (NULL) index (NULL) name1 202 (NULL) 100 11.11 Using where
И EXPLAIN ANALYZE выдает следующее:
-> Limit: 100 row(s) (actual time=24782.146..24782.146 rows=0 loops=1)
-> Filter: (candidate.name1 like '%something%') (cost=9.88 rows=11) (actual time=24782.145..24782.145 rows=0 loops=1)
-> Index scan on candidate using name1 (cost=9.88 rows=100) (actual time=13.970..24755.974 rows=107839 loops=1)
CREATE TABLE код для «пользователя»:
CREATE TABLE `user` (
`id` INT(10,0) NOT NULL AUTO_INCREMENT,
`name1` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_0900_ai_ci',
`name2` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_0900_ai_ci',
PRIMARY KEY (`id`) USING BTREE,
INDEX `name1` (`name1`) USING BTREE,
INDEX `name2` (`name2`) USING BTREE
)
COLLATE='utf8mb4_0900_ai_ci'
ENGINE=InnoDB;
UPDATE 2: ОК, поэтому я провел много экспериментов с ORDER BY и последовательно повторяется следующее: «ORDER BY LIMIT 100» быстро, если является первичным ключом или не имеет ключа любого вида, но медленно, если имеет регулярный ключ. «ORDER BY, LIMIT 100» медленно, если является обычным ключом, и является первичным ключом, но быстро в любой другой комбинации первичного / обычного ключа или без ключа, включая (первичный, обычный).
Кто-нибудь знаете, что здесь происходит? Ничего из этого не имеет никакого смысла !!!