Покрывающий индекс не показывает ожидаемую производительность

#mysql #sql #database #indexing

#mysql #sql #База данных #индексирование

Вопрос:

У меня есть две таблицы одинаковой структуры. Я добавил индекс для столбцов одной таблицы и покрыл индекс для других tales. Структура таблицы следующая

 CREATE TABLE IF NOT EXISTS `customer` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL DEFAULT 'first_name',
  `last_name` varchar(255) NOT NULL DEFAULT 'last_name',
  `pin` bigint(music) NOT NULL DEFAULT '679339',
  `event_time` bigint(20) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COMMENT='test db' AUTO_INCREMENT=1 ;
  

Добавлены индексы для таблиц с использованием следующих запросов

Table1 (обычный индекс)

 alter table customer add INDEX(name)

alter table customer add INDEX(event_time)
  

Table2 (охватываемый индекс)

 alter table customer_tb add INDEX(name,event_time)
  

Вставил 100 000 записей в обе таблицы и выполнил следующий запрос::

 "select name, event_time from customer_tb group by event_time order by event_time"
  

Время запроса для индексированной таблицы: 0,185 сек

Время запроса для покрытой индексированной таблицы: 1.29 сек.

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

Запрос, используемый для покрытия индекса, следует:

 alter table customer_tb add INDEX(name,event_time)
  

Ответ №1:

У вас есть индекс, охватывающий оба столбца, на которые ссылаются в запросе, но вы определили индекс со столбцами в неправильном порядке. Вы должны определить их таким образом:

 ALTER TABLE customer_tb ADD INDEX(event_time,name);
  

Порядок столбцов в индексе имеет большое значение. Моя любимая аналогия с индексом — телефонная книга. Если я попрошу вас найти в телефонной книге любое имя с фамилией «Смит», это будет легко. Но если я попрошу вас найти любое имя с именем «Джон», то тот факт, что книга предварительно отсортирована, вам не поможет.

Аналогично, если я попрошу вас предоставить список фамилий и общее количество людей с каждой фамилией, вы можете сделать это, пролистав книгу, и вы узнаете, что все вхождения данной фамилии собраны вместе. Таким образом, вам не нужно отслеживать, сколько из каждой фамилии вы видели, вы просто подсчитываете их, и когда вы находите другую фамилию, вы сообщаете текущую сумму и начинаете сначала.

Но если я попрошу вас сообщить мне количество людей с каждым именем, внезапно это станет намного сложнее, потому что они разбросаны по всей книге. Вы должны вести не один текущий подсчет, а N текущих подсчетов, по одному для каждого возможного имени.

Комментарии:

1. Спасибо.!!. Я изменил индексацию в соответствии с вашим предложением. Но результат для охватываемого индекса и обычного индекса почти одинаков для 10000 записей. Я ожидаю более быстрого индекса покрытия производительности.

2. Я бы проверил EXPLAIN для этого запроса, чтобы убедиться, что он использует новый индекс. А также убедитесь, что ваш innodb_buffer_pool_size достаточно велик для хранения индекса, потому что производительность будет плохой, если ему придется загружать индекс при каждом запросе.