В MySQL 8.0 простой SELECT работает очень медленно без причины, в то время как в 5.6 работает быстро - PullRequest
0 голосов
/ 24 апреля 2020

У меня есть 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» медленно, если является обычным ключом, и является первичным ключом, но быстро в любой другой комбинации первичного / обычного ключа или без ключа, включая (первичный, обычный).

Кто-нибудь знаете, что здесь происходит? Ничего из этого не имеет никакого смысла !!!

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