Mysql покрытие против композитного против индекса столбца - PullRequest
34 голосов
/ 21 ноября 2011

В следующем запросе

SELECT  col1,col2
FROM    table1
WHERE   col3='value1'
  AND   col4='value2'

Если у меня есть 2 отдельных индекса, один на col3 , а другой на col4 , какой из них будет использоватьсяв этом запросе?

Я где-то читал, что для каждой таблицы в запросе используется только один индекс.Означает ли это, что в запросе нет способа использовать оба индекса?

Во-вторых, если я создал составной индекс, используя оба col3 и col4 вместе, но использовалтолько col3 в предложении WHERE будет ли это хуже для производительности?пример:

SELECT  col1,col2
FROM    table1
WHERE   col3='value1'

Наконец, лучше ли во всех случаях просто использовать индексы покрытия?и отличается ли он между MYISAM и механизмами хранения innodb?

Ответы [ 4 ]

41 голосов
/ 21 ноября 2011

Индекс покрытия не совпадает с составным индексом.

Если у меня есть 2 отдельных индекса, один на col3, а другой на col4, какой из них будет использоваться в этом запросе?

Индекс с наивысшей кардинальностью.
MySQL хранит статистику того, какие индексы имеют какие свойства.
Будет использован индекс, который обладает наибольшей способностью различения (как видно из статистики MySQL).

Я где-то читал, что для каждой таблицы в запросе используется только один индекс. Означает ли это, что в запросе нельзя использовать оба индекса?

Вы можете использовать подвыбор.
Или даже лучше использовать составной индекс, который включает как col3, так и col4.

Во-вторых, если я создал составной индекс, используя и col3, и col4 вместе, но использовал только col3 в предложении WHERE, будет ли это хуже для производительности? пример:

Составной индекс
Правильный термин - индекс compound, а не составной.
Будет использоваться только самая левая часть составного индекса.
Так что, если индекс определен как

index myindex (col3, col4)  <<-- will work with your example.
index myindex (col4, col3)  <<-- will not work. 

См .: http://dev.mysql.com/doc/refman/5.0/en/multiple-column-indexes.html

Обратите внимание, что если вы выберете крайнее левое поле, вы можете избежать использования этой части индекса в предложении where.
Представьте, что у нас есть составной индекс

Myindex(col1,col2)

SELECT col1 FROM table1 WHERE col2 = 200  <<-- will use index
SELECT * FROM table1 where col2 = 200     <<-- will NOT use index.  

Причина, по которой это работает, заключается в том, что первый запрос использует индекс покрытия и сканирует его.
Второй запрос должен получить доступ к таблице и по этой причине сканировать, хотя индекс не имеет смысла.
Это работает только в InnoDB.

Что такое индекс покрытия
Индекс покрытия относится к случаю, когда все поля, выбранные в запросе, имеют индекс covered, в этом случае InnoDB (не MyISAM) никогда не будет считывать данные в таблице, а будет использовать только данные в индексе, что значительно ускоряет до выбора.
Обратите внимание, что в InnoDB первичный ключ включен во все вторичные индексы, поэтому в некотором смысле все вторичные индексы являются составными.
Это означает, что если вы выполните следующий запрос на InnoDB:

SELECT indexed_field FROM table1 WHERE pk = something

MySQL всегда будет использовать индекс покрытия и не будет обращаться к фактической таблице.

5 голосов
/ 21 ноября 2013

Я проголосовал Ответ Йохана за полноту, но Я думаю, что следующее утверждение, которое он делает относительно вторичных индексов, неверно и / или сбивает с толку;

Note that in InnoDB the primary key is included in all secondary indexes, 
so in a way all secondary indexes are compound indexes.

This means that if you run the following query on InnoDB:

SELECT indexed_field FROM table1 WHERE pk = something

MySQL will always use a covering index and will not access the actual table.

ХотяЯ согласен, что первичный ключ - ВКЛЮЧЕНО во вторичном индексе, Я не согласен, MySQL "всегда будет использовать закрывающий индекс" в запросе SELECT, указанном здесь.

Чтобы понять почему, обратите внимание, что в этом случае всегда требуется полный индекс "scan" .Это не то же самое, что операция «поиск», но это 100% сканирование содержимого вторичного индекса.Это связано с тем, что вторичный индекс не упорядочен по первичному ключу;он упорядочен "indexed_field" ( в противном случае он не будет очень полезен в качестве индекса! ).

В свете этого последнего факта будут случаи, когда он более эффективен для«искать» первичный ключ, а затем извлекать indexed_field «из фактической таблицы», а не из вторичного индекса.

1 голос
/ 21 ноября 2011

Это вопрос, который я часто слышу, и есть много путаницы вокруг проблем из-за:

  • Различия в MySQL на протяжении многих лет.Индексы и поддержка нескольких индексов менялись с годами (в сторону поддержки)

  • различия InnoDB / myISAM Существуют некоторые ключевые различия (ниже), но я не верю, что несколько индексов являются одним из них

MyISAM старше, но проверен.Данные в таблицах MyISAM разделены между тремя различными файлами для: - формата таблицы, данных и индексов.
InnoDB относительно новее, чем MyISAM, и безопасен для транзакций.InnoDB также обеспечивает блокировку строк, в отличие от блокировки таблиц, которая повышает многопользовательский параллелизм и производительность.InnoDB также имеет ограничения по внешнему ключу.
Благодаря функции блокировки строк InnoDB хорошо подходит для сред с высокой нагрузкой.

Чтобы быть уверенным в этом, обязательно используйте объяснение_плана для анализа выполнения запроса.

0 голосов
/ 03 июня 2013

Составной индекс не совпадает с составной индекс.

  • Составной индекс охватывает все столбцы в вашем фильтре, объединяет и выбирает критерии. Все эти столбцы хранятся на всех страницах индекса соответственно в B-дереве индекса.
  • Составной индекс охватывает все ключевые столбцы фильтра и соединения в B-дереве, но сохраняет столбцы select только на листовых страницах, поскольку они не будут искать, а только извлекаться! Это экономит место и, следовательно, создает меньше индексных страниц, следовательно, более быстрый ввод-вывод.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...