MySQL: Почему этот SQL-запрос не использует индекс?

У меня есть очень простой SELECT, который прибегает к сортировке файлов и не использует индекс.

Рассмотрим следующий запрос:

SELECT * FROM forum_topic
WHERE topic_status = 0
ORDER BY modified_date LIMIT 0, 30

в следующей таблице (убрано несколько столбцов, чтобы сделать его здесь более кратким)

CREATE TABLE `forum_topic` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`slug` varchar(255) NOT NULL,
`forum_id` int(10) NOT NULL DEFAULT '1',
`title` varchar(100) NOT NULL,
`topic_status` tinyint(1) NOT NULL DEFAULT '0',
`post_count` bigint(20) NOT NULL DEFAULT '0',
`modified_date` datetime NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `slug` (`slug`),
  FULLTEXT KEY `title` (`title`),
  KEY `modified` (`modified_date`, `topic_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

EXPLAIN дает следующий вывод

id  select_type table?      partitions? type?   possible_keys?  key?    key_len?    ref?    rows?   Extra?
1   SIMPLE      forum_topic NULL        ALL     NULL            NULL    NULL    NULL    2075    Using where; Using filesort

Обратите внимание, как в объяснении говорится, что для возможных_ключей есть NULL, и как он использует файловую сортировку после сканирования ВСЕХ строк.

Пожалуйста посоветуй. Спасибо.


person Adergaard    schedule 17.12.2014    source источник
comment
Ваш индекс modified может иметь поля в обратном порядке; а сколько рядов?   -  person Andrew Barber    schedule 17.12.2014


Ответы (1)


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

У вас есть

   KEY `modified` (`modified_date`, `topic_status`)

и вы можете хотеть

   KEY `mod2` (`topic_status`, `modified_date` )

вместо. Это может удовлетворить как фильтр, так и ORDER BY ... LIMIT часть запроса.

Совет для профессионалов: избегайте SELECT * и вместо этого перечисляйте столбцы, которые вам действительно нужны.

Совет для профессионалов: сортировка файлов не обязательно означает то, что вы думаете. Он используется всякий раз, когда MySQL необходимо построить промежуточный набор результатов для таких вещей, как сортировка.

person O. Jones    schedule 17.12.2014
comment
Ну, что ж, спасибо. Тем не менее, теперь он использует условие индекса, но по-прежнему должен использовать все строки. Кроме того, при добавлении к этому нескольких ЛЕВЫХ СОЕДИНЕНИЙ, чтобы получить такие вещи, как имена пользователей и имя форума из других таблиц, он снова прибегает к использованию условия индекса; Использование временного; Использование файловой сортировки — это нехорошо, верно? - person Adergaard; 17.12.2014