Меня действительно интересует, как работают индексы MySQL, в частности, как они могут возвращать запрошенные данные без сканирования всей таблицы?
Это не по теме, я знаю, но если есть кто-то, кто мог бы объяснить мне это подробно, я был бы очень, очень благодарен.
SELECT * FROM members WHERE id = '1'
- так почему с индексом он работает быстрее? Что этот индекс делает здесь?Ответы:
По сути, индекс таблицы работает как индекс в книге (отсюда и название):
Допустим, у вас есть книга о базах данных, и вы хотите найти некоторую информацию, скажем, о хранилище. Без индекса (при условии отсутствия другой помощи, такой как оглавление) вам пришлось бы просматривать страницы одну за другой, пока вы не найдете тему (это так
full table scan
). С другой стороны, в индексе есть список ключевых слов, поэтому вы можете просмотреть его и увидеть, чтоstorage
упомянуто на страницах 113-120, 231 и 354. Затем вы можете переходить на эти страницы напрямую, без поиска (это поиск с индекс, несколько быстрее).Конечно, насколько полезным будет индекс, зависит от многих вещей - несколько примеров, используя приведенное выше сравнение:
источник
Первое, что вы должны знать, это то, что индексы - это способ избежать сканирования полной таблицы, чтобы получить результат, который вы ищете.
Существуют разные виды индексов, и они реализованы на уровне хранилища, поэтому между ними нет стандарта, и они также зависят от используемого вами механизма хранилища.
InnoDB и индекс дерева B +
Для InnoDB наиболее распространенным типом индекса является индекс на основе B + Tree, в котором элементы хранятся в отсортированном порядке. Кроме того, вам не нужно обращаться к реальной таблице, чтобы получить индексированные значения, что делает ваш запрос более быстрым.
«Проблема» в этом типе индекса заключается в том, что вы должны запросить крайнее левое значение, чтобы использовать индекс. Итак, если в вашем индексе есть два столбца, скажем, last_name и first_name, порядок, в котором вы запрашиваете эти поля, имеет большое значение .
Итак, с учетом следующей таблицы:
Этот запрос будет использовать индекс:
Но следующий не будет
Потому что вы
first_name
сначала запрашиваете столбец, а это не самый левый столбец в индексе.Этот последний пример еще хуже:
Потому что теперь вы сравниваете самую правую часть самого правого поля в индексе.
Индекс хеша
Это другой тип индекса, который, к сожалению, поддерживает только серверная часть памяти. Это молниеносно, но полезно только для полных поисков, что означает, что вы не можете использовать его для таких операций, как
>
,<
илиLIKE
.Так как он работает только для памяти, вы, вероятно, не будете использовать его очень часто. Основной случай, о котором я могу подумать сейчас, - это то, что вы создаете временную таблицу в памяти с набором результатов из другого выбора и выполняете много других выборов в этой временной таблице, используя хэш-индексы.
Если у вас большое
VARCHAR
поле, вы можете «эмулировать» использование хеш-индекса при использовании B-дерева, создав другой столбец и сохранив на нем хеш-значение большого значения. Допустим, вы храните URL-адрес в поле, а значения довольно большие. Вы также можете создать целочисленное поле с именемurl_hash
и использовать хеш-функцию, например,CRC32
или любую другую хеш-функцию для хеширования URL-адреса при его вставке. И затем, когда вам нужно запросить это значение, вы можете сделать что-то вроде этого:Проблема с приведенным выше примером состоит в том, что, поскольку
CRC32
функция генерирует довольно маленький хэш, вы получите множество коллизий в хэшированных значениях. Если вам нужны точные значения, вы можете решить эту проблему, выполнив следующие действия:Все еще стоит хэшировать вещи, даже если число коллизий велико, потому что вы будете выполнять только второе сравнение (строковое) с повторяющимися хешами.
К сожалению, используя эту технику, вам все равно нужно попасть в таблицу, чтобы сравнить
url
поле.Заворачивать
Некоторые факты, которые вы можете учитывать каждый раз, когда хотите поговорить об оптимизации:
Целочисленное сравнение намного быстрее, чем сравнение строк. Это можно проиллюстрировать на примере об эмуляции хеш-индекса в
InnoDB
.Возможно, добавление дополнительных шагов в процесс делает его быстрее, а не медленнее. Это может быть проиллюстрировано тем фактом, что вы можете оптимизировать a
SELECT
, разделив его на два этапа, сделав первый из них, сохраняя значения во вновь созданной таблице в памяти, а затем выполняя более сложные запросы для этой второй таблицы.В MySQL есть и другие индексы, но я думаю, что B + Tree один из наиболее используемых когда-либо, и хэш-это полезно знать, но другие можно найти в документации MySQL .
Я настоятельно рекомендую вам прочитать книгу «High Performance MySQL», ответ на которую был определенно основан на главе об индексах.
источник
SELECT last_name, first_name FROM person WHERE last_name= "Constantine"
2.SELECT last_name, first_name FROM person WHERE last_name LIKE "%Constantine"
По сути, индекс - это карта всех ваших ключей, отсортированная по порядку. Имея список по порядку, вместо проверки каждого ключа он может сделать что-то вроде этого:
1: Перейти к середине списка - выше или ниже того, что я ищу?
2: Если выше, перейдите к половине пути между серединой и дном, если ниже, посередине и сверху
3: выше или ниже? Снова перейти к средней точке и т. Д.
Используя эту логику, вы можете найти элемент в отсортированном списке примерно за 7 шагов вместо проверки каждого элемента.
Очевидно, что есть сложности, но это дает вам основную идею.
источник
Взгляните на эту ссылку: http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html
То, как они работают, слишком широко, чтобы освещать это в одном посте.
Вот одно из лучших объяснений индексов, которые я видел. К сожалению, это для SQL Server, а не MySQL. Я не уверен, насколько похожи эти два ...
источник
Возьмите это видео для более подробной информации об индексировании
Простое индексирование Вы можете создать уникальный индекс для таблицы. Уникальный индекс означает, что две строки не могут иметь одинаковое значение индекса. Вот синтаксис для создания индекса на таблице
Вы можете использовать один или несколько столбцов для создания индекса. Например, мы можем создать индекс
tutorials_tbl
использования tutorial_author.Вы можете создать простой индекс для таблицы. Просто пропустите ключевое слово UNIQUE из запроса, чтобы создать простой индекс. Простой индекс позволяет дублировать значения в таблице.
Если вы хотите проиндексировать значения в столбце в порядке убывания, вы можете добавить зарезервированное слово DESC после имени столбца.
источник
Я хочу добавить свои 2 цента. Я далек от того, чтобы быть экспертом по базам данных, но недавно я немного прочитал эту тему; достаточно для меня, чтобы попытаться дать ELI5. Итак, вот объяснение для неспециалистов.
Я так понимаю, что индекс подобен мини-зеркалу вашей таблицы, почти как ассоциативный массив. Если вы передадите ему соответствующий ключ, вы можете просто перейти к этой строке в одной «команде».
Но если у вас не было этого индекса / массива, интерпретатор запросов должен использовать цикл for, чтобы пройти по всем строкам и проверить совпадение (сканирование полной таблицы).
Наличие индекса имеет «обратную сторону» дополнительного хранилища (для этого мини-зеркала) в обмен на «обратную сторону» поиска контента быстрее.
Обратите внимание, что (в зависимости от вашего движка БД) создание первичных, внешних или уникальных ключей автоматически устанавливает соответствующий индекс. Тот же принцип в основном почему и как работают эти ключи.
источник
Добавление визуального представления в список ответов.
MySQL использует дополнительный уровень косвенности: записи вторичного индекса указывают на записи первичного индекса, а сам первичный индекс содержит расположения строк на диске. Если смещение строки изменяется, необходимо обновить только первичный индекс.
Предостережение: структура данных диска выглядит плоской на диаграмме, но на самом деле представляет собой дерево B +.
Источник: ссылка
источник
В MySQL InnoDB есть два типа индекса.
Первичный ключ, который называется кластеризованным индексом. Ключевые слова индекса хранятся с реальными данными записи в листовом узле B + Tree.
Вторичный ключ, который не является кластеризованным индексом. Эти индексы хранят только ключевые слова первичного ключа вместе со своими собственными ключевыми словами индекса в листовом узле B + Tree. Поэтому при поиске по вторичному индексу он сначала найдет ключевые слова индекса первичного ключа и просканирует первичный ключ B + Tree, чтобы найти записи реальных данных. Это замедлит вторичный индекс по сравнению с поиском первичного индекса. Однако, если все
select
столбцы находятся во вторичном индексе, нет необходимости снова искать первичный индекс B + Tree. Это называется индексом покрытия.источник