Как работают индексы MySQL?

меня действительно интересует, как работают индексы MySQL, более конкретно, как они могут возвращать запрошенные данные без сканирования всей таблицы?

Это не по теме, я знаю, но если есть кто-то, кто мог бы объяснить мне подробно, я буду очень, очень благодарен.

6 ответов


в основном индекс на таблице работает как индекс в книге (Вот откуда взялось имя):

full table scan). С другой стороны, индекс имеет список ключевых слов, поэтому вы обратитесь к индексу и увидите, что storage is упомянутые на стр. 113-120,231 и 354. Затем вы можете перейти на эти страницы напрямую, без поиска (это поиск с индексом, несколько быстрее).

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

  • если бы у вас была книга по базам данных и проиндексировано слово "база данных", вы бы увидели,что он упоминается на страницах 1-59, 61-290 и 292 до 400. В таком случае индекс не очень помогает, и он может быть быстрее чтобы пройти через страницы один за другим (в базе данных это "плохая избирательность").
  • для 10-страничной книги нет смысла делать индекс, так как вы можете получить 10-страничную книгу с префиксом 5-страничного индекса, что просто глупо - просто отсканируйте 10 страниц и покончите с этим.
  • индекс также должен быть полезен - обычно нет смысла индексировать, например, частоту буквы " L " на странице.

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

существуют различные типы индексов, и они реализованы на уровне хранения, поэтому между ними нет стандарта, и они также зависят от используемого механизма хранения.

InnoDB и индекс дерева B+

для InnoDB наиболее распространенным типом индекса является индекс на основе дерева B+, в котором хранится элементы в отсортированном порядке. Кроме того, вам не нужно обращаться к реальной таблице, чтобы получить индексированные значения, что делает ваш запрос быстрее.

"проблема" в этом типе индекса заключается в том, что вам нужно запросить крайнее левое значение для использования индекса. Итак, если ваш индекс имеет два столбца, скажем last_name и first_name, порядок запроса этих полей важно!.

Итак, учитывая следующую таблицу:

CREATE TABLE person (
    last_name VARCHAR(50) NOT NULL,
    first_name VARCHAR(50) NOT NULL,
    INDEX (last_name, first_name)
);

этот запрос воспользуйтесь индексом:

SELECT last_name, first_name FROM person
WHERE last_name = "John" AND first_name LIKE "J%"

но следующий не будет

SELECT last_name, first_name FROM person WHERE first_name = "Constantine"

потому что вы спрашиваете first_name столбец первый, и это не самый левый столбец в индексе.

этот последний пример еще хуже:

SELECT last_name, first_name FROM person WHERE first_name LIKE "%Constantine"

потому что теперь вы сравниваете самую правую часть самого правого поля в индексе.

хэш-индекс

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

поскольку он работает только для бэкэнда памяти, вы, вероятно, не будете использовать его очень часто. Основной случай, о котором я могу думать прямо сейчас, - это тот, когда вы создаете временную таблицу в памяти с набором результатов из другого select и выполняете много других Select в этой временной таблице, используя хэш индексы.

если у вас большая VARCHAR поле, вы можете "эмулировать" использование хэш-индекса при использовании B-дерева, создавая другой столбец и сохраняя хэш большого значения на нем. Предположим, вы храните url-адрес в поле, и значения довольно большие. Вы также можете создать целое поле с именем url_hash и используйте хэш-функцию, например CRC32 или любая другая хэш-функция для хэширования url-адреса при его вставке. А затем, когда вам нужно запросить это значение, вы можете сделать что-то подобное это:

SELECT url FROM url_table WHERE url_hash=CRC32("http://gnu.org");

проблема с приведенным выше примером, что с CRC32 функция генерирует довольно маленький хэш, вы получите много столкновений в хэшированных значениях. Если вам нужны точные значения, вы можете исправить эту проблему, выполнив следующие действия:

SELECT url FROM url_table 
WHERE url_hash=CRC32("http://gnu.org") AND url="http://gnu.org";

по-прежнему стоит хэшировать вещи, даже если номер столкновения высок, потому что вы будете выполнять только второе сравнение (строковое) против повторяющихся хэшей.

к сожалению, используя эту технику, вам все равно нужно попасть в таблицу, чтобы сравнить


в основном индекс-это карта всех ваших ключей, которая сортируется по порядку. Со списком в порядке, то вместо проверки каждого ключа, он может сделать что-то вроде этого:

1: Перейдите в середине списка - выше или ниже, чем то, что я ищу?

2: если выше, перейдите на полпути между серединой и дном, если ниже, середина и верх

3: выше или ниже? Снова перейти к средней точке и т. д.

используя эту логику, вы можете найти элемент в сортированный список примерно за 7 шагов, вместо проверки каждого элемента.

очевидно, что есть сложности, но это дает вам основную идею.


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

индекс базы данных похож на индекс книги. Если вы хотите найти тему, сначала посмотрите в индексе, а затем откройте страницу с темой без сканирования всего книга.

настоятельно рекомендуется создать индекс для столбцов таблицы, из которых часто запрашиваются данные. Обратите внимание, что все столбцы первичного ключа находятся в первичном индексе таблицы автоматически.

если index помогает ускорить запрос данных, почему мы не используем индексы для всех столбцов? Если вы создаете индекс для каждого столбца, MySQL должен построить и поддерживать таблицу индекса. Всякий раз, когда изменения вносятся в записи таблицы, MySQL должен перестроить индекс, который занимает время, а также снижает производительность сервера баз данных. Создание Индекса MySQL

вы часто создаете индексы при создании таблиц. MySQL автоматически добавляет любой столбец, объявленный как первичный ключ, ключ, уникальный или индекс к индексу. Кроме того, можно добавить индексы в таблицы, в которых уже есть данные.

для создания индексов используется инструкция CREATE INDEX. Ниже показан синтаксис CREATE INDEX заявление: Один Два 3

CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name USING [BTREE | HASH | RTREE] ON table_name (column_name [(length)] [ASC | DESC],...)

во-первых, вы указываете индекс на основе типа таблицы или механизма хранения:

UNIQUE означает, что MySQL создаст ограничение, что все значения в индексе должны быть уникальными. Дублировать значение null во всех двигателей, кроме ББР. Полнотекстовый индекс поддерживается только MyISAM storage engine и принимается только для столбца с типом данных CHAR, VARCHAR или TEXT. Пространственный индекс поддерживает пространственный столбец и доступен на MyISAM подсистема хранилища. Кроме того, значение столбца не должно быть NULL.

затем вы называете индекс и его тип после ключевого слова USING, такого как BTREE, HASH или RTREE, также на основе механизма хранения таблицы.

вот механизмы хранения таблицы с соответствующими разрешенными типами индексов: Допустимые Типы Индексов Двигателя Хранения MyISAM BTREE, RTREE InnoDB в дерево ХЭШ ПАМЯТИ / КУЧИ, BTREE NDB HASH

в-третьих, вы объявляете имя таблицы и столбцы списка вы хотите добавить в индекс. Пример создания индекса в MySQL

в образце базы данных можно добавить столбец officeCode таблицы employees в индекс с помощью инструкции CREATE INDEX следующим образом: 1

CREATE INDEX officeCode ON employees(officeCode)

Удаление Индексов

помимо создания индекса, вы также можете удалить индекс с помощью оператора DROP INDEX. Интересно, что оператор DROP INDEX также сопоставляется с оператором ALTER TABLE. Следующий синтаксис удаление индекса: 1

DROP INDEX index_name ON table_name

например, если вы хотите удалить индекс officeCode таблицы employees, которую мы создали выше, вы можете выполнить следующий запрос: 1

DROP INDEX officeCode ON employees


принимать по этой видео для более подробной информации о индексации

Простой Индексации Можно создать уникальный индекс для таблицы. Уникальный индекс означает, что две строки не могут иметь одно и то же значение индекса. Вот синтаксис для создания индекса в таблице

CREATE UNIQUE INDEX index_name
ON table_name ( column1, column2,...);

для создания индекса можно использовать один или несколько столбцов. Например, мы можем создать индекс tutorials_tbl использование tutorial_author.

CREATE UNIQUE INDEX AUTHOR_INDEX
ON tutorials_tbl (tutorial_author)

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

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

mysql> CREATE UNIQUE INDEX AUTHOR_INDEX
ON tutorials_tbl (tutorial_author DESC)

взгляните на эту ссылку:http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html

как они работают, слишком широкая тема для освещения в одном сообщении SO.

здесь это одно из лучших объяснений индексов, которые я видел. К сожалению, это для SQL Server, а не MySQL. Я не уверен, насколько они похожи...