Индекс нескольких столбцов против нескольких индексов - PullRequest
12 голосов
/ 31 августа 2011

У меня есть следующая таблица в базе данных 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, индексные ключи.Я думал об этом потому, что предложение 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

ПРИМЕЧАНИЕ: Это не использование индекса из нескольких столбцов, это результат использования приведенного выше описания таблицы.

Ответы [ 2 ]

13 голосов
/ 31 августа 2011

Вы должны использовать многостолбцовый индекс для (primaryId, imgDate), чтобы MySQL мог использовать его для выбора строк и сортировки.

Если все столбцы, используемые для сортировки, не входят в индекс, используемый для выбора, MySQL использует стратегию « filesort », которая состоит в сортировке всех строк (в памяти, если строк не слишком много; на диске остальное).

Если в индексе есть все столбцы, используемые для сортировки, MySQL использует индекс для получения порядка строк (с некоторыми ограничениями).

MySQL использует древовидную структуру для индексов. Это позволяет напрямую получать ключи по порядку без сортировки.

Многостолбцовый индекс - это, в основном, индекс объединения столбцов. Это позволяет MySQL найти первую строку, соответствующую primaryId={$imgId}, а затем получить доступ ко всем другим строкам непосредственно в правильном порядке.

С индексом в одну строку на primaryId MySQL может найти все строки, соответствующие primaryId={$imgId}, но он найдет строки в произвольном порядке; так что после этого придется их сортировать.

См. ОБЪЯСНИТЬ и ЗАКАЗАТЬ ПО ОПТИМИЗАЦИИ .

11 голосов
/ 31 августа 2011

Ваше объяснение выглядит так:

[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.Вполне нормально- Использование сортировки файлов: результат вашего запроса настолько велик, что его невозможно отсортировать в памяти.MySQL должен записать его в файл, отсортировать файл и затем вывести.Это означает доступ к диску и замедлит все.Часто помогает добавление индекса, который может помочь в сортировке, но решение «использования сортировки файлов» - это отдельная глава.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...