Множественный индекс столбцов против нескольких индексов
У меня есть следующая таблица в базе данных MySQL:
CREATE TABLE `secondary_images` (
`imgId` int(10) unsigned NOT NULL AUTO_INCREMENT,
`primaryId` int(10) unsigned DEFAULT NULL,
`view` varchar(255) DEFAULT NULL,
`imgURL` varchar(255) DEFAULT NULL,
`imgDate` datetime DEFAULT NULL,
PRIMARY KEY (`imgId`),
KEY `primaryId` (`primaryId`),
KEY `imgDate` (`imgDate`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ;
SQL будет выглядеть следующим образом:
SELECT imgURL, view FROM secondary_images
WHERE primaryId={$imgId} ORDER BY imgDate DESC
Как вы можете видеть, я сделал клавиши primaryId
и imgDate
, Index Keys. Я думал об этом потому, что предложение WHERE
запрашивает результаты с использованием primaryId
, а предложение ORDER
использует imgDate
.
Мой вопрос: было бы лучше использовать несколько индексов, как я сейчас? Или мне нужно указать индекс нескольких столбцов (что-то я не очень хорошо понимаю в данный момент)?
Это то, что я получаю от EXPLAIN:
id = 1
select_type = simple
table = secondary_images
type = ref
possible_keys = primaryId
key = primaryId
key_len = 5
ref = const
rows = 1
extra = Using where; Using filesort
ПРИМЕЧАНИЕ.. Это не использование индекса нескольких столбцов, это результат использования приведенного выше описания таблицы.
Ответы
Ответ 1
Вам следует использовать индекс с несколькими столбцами (primaryId, imgDate), чтобы MySQL мог использовать его для выбора строк и сортировки.
Если все столбцы, используемые для сортировки, не находятся в индексе, используемом для выбора, MySQL использует стратегию "filesort", которая состоит из сортировки всех строк (в памяти, если на диске еще не так много строк).
Если все столбцы, используемые для сортировки, находятся в индексе, MySQL использует индекс, чтобы получить порядок строк (с некоторыми ограничениями).
MySQL использует древовидную структуру для индексов. Это позволяет напрямую обращаться к клавишам без сортировки.
Многоколоночный индекс в основном является индексом конкатенации столбцов. Это позволяет MySQL найти первую строку, соответствующую primaryId={$imgId}
, а затем получить доступ ко всем другим строкам в правильном порядке.
С индексом с одной строкой в primaryId
MySQL может найти все строки, соответствующие primaryId={$imgId}
, но он найдет строки в определенном порядке; поэтому после этого им придется сортировать их.
Смотрите EXPLAIN и ОПРЕДЕЛЕНИЕ ЗАКАЗА.
Ответ 2
Ваше объяснение выглядит следующим образом:
[id] => 1
[select_type] => SIMPLE
[table] => secondary_images
[type] => ref
[possible_keys] => primaryId
[key] => primaryId
[key_len] => 5
[ref] => const
[rows] => 1
[Extra] => Using where; Using filesort
Пройдите через него.
[id] => 1
О том, что мы говорим о первой таблице. Вы вызываете только одну таблицу в своем заявлении.
[select_type] => SIMPLE
Мы делаем простой SELECT.
[table] => secondary_images
Имя таблицы, о которой идет речь.
[type] => ref
Тип выбора, наиболее важный для объединений.
[possible_keys] => primaryId
Это важное поле: оно показывает, какие ключи можно использовать для ускорения выполнения запроса. В этом случае считается полезным только ваш первичный ключ.
[key] => primaryId
Это важное поле: оно показывает, какие ключи были окончательно использованы. В этом случае первичный ключ.
[key_len] => 5
[ref] => const
[rows] => 1
Угадывает количество строк, проверенных запросом.
[Extra] => Using where; Using filesort
наиболее важное поле imho.
- Использование где: вы используете инструкцию where. Совсем хорошо.
- Использование filesort: результат вашего запроса настолько велик, что он не может быть отсортированы по памяти. MySQL должен записать его в файл, отсортировать файл и затем выведите. Это означает, что доступ к диску и будет замедлять все. Добавление индекса, которое может помочь сортировке, часто помогает, но решение "using filesort" - это отдельная глава.