Оптимизатор запросов MySQL, показывающий случайное поведение для запроса к таблице с первичными и составными индексами - PullRequest
0 голосов
/ 19 сентября 2019

У меня есть таблица MySQL, по которой я выполняю запрос.Запрос в некоторых случаях занимает много времени ~ 15 минут, но в других случаях он возвращает результаты в течение миллисекунд.Два запроса отличаются только значением столбца в предложении where.

Синтаксис таблицы

CREATE TABLE `tests` (
  `id` varchar(36) NOT NULL,
  `some_other_id` varchar(36) NOT NULL,
  `col_1` varchar(64) NOT NULL,
  `col_2` varchar(128) DEFAULT NULL,
  `col_3` varchar(64) DEFAULT NULL,
  `status` varchar(32) NOT NULL,
  `created_at_epoch` bigint(20) NOT NULL,
  `updated_at_epoch` bigint(20) NOT NULL,
  `updated_by` varchar(64) NOT NULL,
  `version` int(11) NOT NULL,
  `col_4` text,
  `col_5` varchar(64) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `some_other_id_col_1_col_2_idx` (`some_other_id`,`col_1`,`col_2`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

id и some_other_id создаются с использованием метки времени и случайных символов после этого. Примером some_other_id является «15632901521370150qGUCAQpVuUWK-bJg»

В таблице содержится ~ 60 миллионов записей с ~ 56 гигабайтами данных.

Обратите внимание на значение some_other_id в следующих запросах.

select test.id, test.col_3, test.col_5, test.created_at_epoch, test.col_2, test.col_1, test.col_4, test.status, test.some_other_id, test.updated_at_epoch, test.updated_by, test.version from tests test where test.some_other_id='**VAL_1**' and (test.status in ('activated')) and test.id>='' order by test.id limit 2;
--Executes within milliseconds.
--Explain plan gives key as "some_other_id_col_1_col_2_idx".

select test.id, test.col_3, test.col_5, test.created_at_epoch, test.col_2, test.col_1, test.col_4, test.status, test.some_other_id, test.updated_at_epoch, test.updated_by, test.version from tests test where test.some_other_id='**VAL_1**' and (test.status in ('activated')) and test.id>='' order by test.id limit 1;
--Takes ~14-15 minutes.
--Explain plan gives key as "PRIMARY".

select test.id, test.col_3, test.col_5, test.created_at_epoch, test.col_2, test.col_1, test.col_4, test.status, test.some_other_id, test.updated_at_epoch, test.updated_by, test.version from tests test where test.some_other_id='**VAL_1**' and (test.status in ('activated')) and test.id>='' order by test.id limit 3;
--Executes within milliseconds.
--Explain plan gives key as "some_other_id_col_1_col_2_idx".

select test.id, test.col_3, test.col_5, test.created_at_epoch, test.col_2, test.col_1, test.col_4, test.status, test.some_other_id, test.updated_at_epoch, test.updated_by, test.version from tests test where test.some_other_id='**VAL_2**' and (test.status in ('activated')) and test.id>='' order by test.id limit 2;
--Takes ~14-15 minutes.
--Explain plan gives key as "PRIMARY".

select test.id, test.col_3, test.col_5, test.created_at_epoch, test.col_2, test.col_1, test.col_4, test.status, test.some_other_id, test.updated_at_epoch, test.updated_by, test.version from tests test where test.some_other_id='**VAL_2**' and (test.status in ('activated')) order by test.id limit 2;
--Takes ~14-15 minutes.
--Explain plan gives key as "PRIMARY".

select test.id, test.col_3, test.col_5, test.created_at_epoch, test.col_2, test.col_1, test.col_4, test.status, test.some_other_id, test.updated_at_epoch, test.updated_by, test.version from tests test where test.some_other_id='**VAL_2**' and (test.status in ('activated')) and test.id>='' limit 2;
--Executes within milliseconds.
--Explain plan gives key as "some_other_id_col_1_col_2_idx".

Я не могу понять поведение здесь и ищу объяснение того, как это могло произойти,Я использую MySQL 5.6

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