#mysql #sql #performance #optimization
#mysql #sql #Производительность #оптимизация
Вопрос:
Структура таблицы:
CREATE TABLE IF NOT EXISTS `newsletters`
(
`id` int(11) NOT NULL auto_increment,
`last_update` int(11) default NULL,
`status` int(11) default '0',
`message_id` varchar(255) default NULL,
PRIMARY KEY (`id`),
KEY `status` (`status`),
KEY `message_id` (`message_id`),
KEY `last_update` (`last_update`)
)
ENGINE=MyISAM DEFAULT CHARSET=latin1;
Запрос:
SELECT id, last_update
FROM newsletters
WHERE status = 1
ORDER BY last_update DESC
LIMIT 0, 100
newsletters
в таблице более 3 миллионов записей- выполнение запроса занимает более 26 секунд
Запрос объясняет:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE newsletters range status status 5 NULL 3043354 Using where; Using filesort
Итак, почему он не использует filesort
, и как это range
запрос?
Ответ №1:
Он используется filesort
для сортировки по last_update
. Вы можете избежать этого, изменив индекс на status, last_update
, чтобы MySQL находил все строки со статусом 1 в правильном порядке.
Для дальнейшей оптимизации измените индекс на status, last_update, id
. Это позволяет MySQL удовлетворять запрос, просто просматривая индекс, без поиска по таблице.
CREATE INDEX idx_newsletters_status
ON newsletters(status, last_update, id);
Комментарии:
1. KEY должен применять индексы так же, как INDEX.
2. Это сделало это, я любитель в оптимизации / индексировании, поэтому я действительно не думал о попытке индексировать несколько столбцов. @Baez: Не могли бы вы, пожалуйста, что вы имеете в виду под этим?
3. @gAMBOOKa: Чтобы представить, какой индекс вам больше всего помог бы, попробуйте представить, какой список в каком порядке больше всего помог бы вам , если бы вы были компьютером, и вам нужно было быстро найти правильные записи и вернуть запрошенную информацию. В этом случае вам нужен список всех записей (поскольку каждый индекс должен содержать все записи), отсортированных сначала по статусу (поскольку вас интересуют только единицы), а затем по last_update (чтобы вы могли быстро получить первые 100 из них). Если вы добавите идентификатор в список, то сможете получить всю свою информацию без необходимости возвращаться к главной таблице.
4. Это очень интуитивный способ объяснить это. Итак, в принципе, я должен добавить индексы в том порядке, в котором будет удалено большинство строк слева направо, правильно?