MySQL медленный порядок по столбцу индекса

#mysql #sql #indexing #sql-order-by

#mysql #sql #индексирование #sql-order-by

Вопрос:

У меня есть таблица (book_list), в которой около 4 миллионов записей. У него есть PK (book_list_id), и когда я запускаю запрос, подобный приведенному ниже, я получаю результаты обратно в .060s

  select * from book_list bl ORDER BY bl.book_list_id LIMIT 25
  

Теперь, когда я запускаю практически тот же запрос, но сортирую по book_title, который является varchar (1200) и индексируется, это занимает 34,7 секунды

  select * from book_list bl ORDER BY bl.book_title LIMIT 25
  

Могу ли я что-нибудь сделать, чтобы ускорить это второе утверждение?

Кстати, я также пробовал сортировать по другим числовым индексированным полям, и они тоже очень медленные. Только сортировка PK, похоже, дает быстрые результаты.

Вот таблица создания:

 CREATE TABLE `book_list` (

`book_list_id` int(11) NOT NULL AUTO_INCREMENT,

`book_title` varchar(1200) CHARACTER SET utf8 DEFAULT NULL
 PRIMARY KEY (`book_list_id`),

 KEY `indx_book_title` (`book_title`(255))

 ) 
 ENGINE=InnoDB AUTO_INCREMENT=4733798 DEFAULT CHARSET=latin1
  

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

1. Пожалуйста, опубликуйте show create table.

2. что показывает запуск ‘explain …’?

3. Возможно, причина просто в том, что отдельные записи индекса составляют 4 байта для столбца integer и 766 байт для столбца varchar. Это больший объем данных для сравнения.

4. Хаммерайт прав. Если длина заголовка равна 1200, а длина индекса равна 255, СУБД следует изменить порядок строк для оставшихся 1200-255 символов, может быть это? 34,7 секунды — это много времени, где узкое место в этот промежуточный период? Диск? ПРОЦЕССОР? Может ли это помочь в этой проблеме? Если вы получите pk для 25 первых строк по заголовку и сделаете запрос, запрашивающий этот жестко закодированный pks, это быстро?

5. вы также можете выполнить «порядок по левому краю (book_title, 255)», что не должно вызвать проблем с использованием индекса. Тем не менее, вы все равно можете получить заголовки, которые содержат более 255 символов, отображаемых не по порядку. Но, по крайней мере, вы можете проверить теорию, не внося никаких изменений в базу данных.

Ответ №1:

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

Увеличьте часть индексируемого поля или сделайте так, чтобы запрос сортировался только по первым 255 символам, как говорит @Dmitry Beransky: «порядок по левому краю (book_title, 255)»

Ответ №2:

Не могли бы вы, пожалуйста, попробовать:

 select * from book_list where book_list_id in
(select book_list_id from book_list order by book_title limit 25);
  

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

1. Это выдает следующую ошибку: [Ошибка] 1235 — Эта версия MySQL еще не поддерживает ‘LIMIT amp; IN /ALL /ANY /НЕКОТОРЫЙ подзапрос’