При поиске определенных данных из кучи данных наши обычно используемые структуры данных представляют собой хеш-таблицы и двоичные деревья поиска.Таблица по сути представляет собой набор данных, поэтому база данных MySQL использует дерево B+ и хэш-таблицу для достижения индекса
Дерево B+ образовано из бинарного дерева поиска, сбалансированного бинарного дерева и дерева B (также известного как B-дерево). самое раннее сбалансированное бинарное дерево, но дерево B+ не является бинарным деревом
Бинарное дерево поиска и сбалансированное бинарное деревоЭффективность бинарного дерева поиска и эффективность поиска сбалансированного бинарного дерева уже очень высоки, почему бы не использовать эти две структуры данных для реализации индекса? Не торопитесь анализировать
Бинарное дерево поиска — это бинарное дерево со специальными свойствами, которые должны удовлетворять следующим свойствам.
-
Нелистовые узлы имеют не более двух дочерних узлов.
-
Значение нелистового узла больше, чем у левого дочернего узла, и меньше, чем у правого дочернего узла.
-
ни один узел с одинаковым значением не повторяется;
Найдите двоичное дерево на рисунке выше.Например, чтобы найти запись со значением ключа 5, сначала найдите корень со значением 6, которое больше 5, найдите левое поддерево 6, найдите 3, 5 больше 3, а затем найти его правое поддерево, всего поиск выполняется 3 раза. Таким же образом требуется 3 раза найти запись со значением ключа 8. Среднее количество поисков всех значений ключа равно (1+2+2+3+3+3)/6=2,3 раза.Если эти значения ключа искать последовательно, среднее количество поисков равно (1+ 2+3+4+5+ 6)/6=3,3 (числа расположены в порядке поиска, первое число должно быть 1 раз, второе число 2 раза и т. д.), очевидно, средняя скорость поиска двоичного дерево поиска быстрее, чем последовательный поиск.
Бинарное дерево поиска может быть построено произвольно, если бинарное дерево поиска построено следующим образом.
Средняя скорость поиска составляет (1+2+3+4+5+5)/6=3,16 раза, что аналогично последовательному поиску. Чтобы повысить эффективность запроса двоичного дерева поиска, необходимо сбалансировать количество двоичных поисков, что приводит к сбалансированному двоичному дереву.
В дополнение к удовлетворению трех вышеуказанных свойств сбалансированное бинарное дерево также должно удовлетворять следующему свойству:
-
Количество уровней в левой и правой частях дерева не будет отличаться более чем на 1
Эффективность поиска сбалансированного бинарного дерева действительно очень высока, но стоимость поддержания сбалансированного бинарного дерева очень высока, и требуется одно или несколько левых и правых вращений, чтобы получить баланс дерева после вставки или Обновить. Просто приведите пример.
Изначально сбалансированное бинарное дерево
Вставка 3
повернуть направо один раз
снова повернуть налево
В качестве научно-популярной статьи я не буду разбирать здесь детали леворукости и праворукости.Поместите несколько картинок для понимания леворукости и праворукости.
Левосторонний x означает превращение x в левый узел
Поверните y вправо, что означает превращение y в правый узел
Оглядываясь назад на левое и правое вращение в приведенном выше примере, ясно ли это?
B-деревья и B+ деревья
B-дерево и B-дерево - это одно и то же дерево. Если индекс реализован с помощью сбалансированного бинарного дерева, эффективность уже очень высока. Количество операций ввода-вывода, выполненных для поиска узла, равно высоте дерева, на котором находится узел. находится, потому что мы не можем загрузить весь индекс в память, а данные узла не упорядочены последовательно на диске. Таким образом, в худшем случае количество операций ввода-вывода на диск равно высоте дерева.
Хотя эффективность поиска сбалансированного бинарного дерева действительно очень высока, узким местом, мешающим повышению производительности, является частый ввод-вывод.Как уменьшить количество операций ввода-вывода? Предшественники очень умно предложили принцип локальности, который делится на принцип локальности времени, то есть, если вы запрашиваете пользовательские данные с идентификатором 1, вы также будете запрашивать данные с идентификатором 1 через определенный период времени, поэтому эта часть данных будет кэширована. В соответствии с принципом пространственной локальности, когда вы запрашиваете данные пользователя с идентификатором 1, у вас есть высокая вероятность запросить данные пользователя с идентификатором 2, 3 и 4, поэтому идентификатор равен 1, 2. , Данные 3 и 4 считываются в память, а самой маленькой единицей является страница.
Понятия B-tree и B+дерева более сложны.Заинтересованные друзья могут нажать на оригинальную ссылку, чтобы увидеть статью, написанную на Zhihu.Здесь только введение в макрос.Как упоминалось выше, высота дерева определяет количество IO.Итак неужели уменьшение высоты дерева не может уменьшить количество IO?Как его уменьшить?Достаточно поставить больше данных на каждую ноду,и эти данные хранятся в одном блоке,что соответствует минимальной единичной странице считанной в БД. , данные могут быть считаны за один ввод-вывод.Хотя количество сравнений может увеличиться, сравнение в памяти на несколько порядков хуже, чем при дисковом вводе-выводе, а общая эффективность все равно повышается.
Итак, B-дерево, которое вы видите, выглядит так
В+ дерево такое
Так в чем же разница между деревом B и деревом B+?
-
B+ отличается от дерева B. Неконечные узлы дерева B+ не сохраняют данные, соответствующие значению ключа, что значительно увеличивает значение ключа, которое может сохранить каждый узел дерева B+;
-
Листовой узел B+ сохраняет все значения ключа родительского узла и данные, соответствующие значению ключа, а значение ключа каждого конечного узла связывается от малого к большому;
-
Количество ключевых значений корневого узла дерева B+ равно количеству его дочерних узлов;
-
Нелистовые узлы B+ выполняют только индексирование данных и не хранят данные, соответствующие фактическому значению ключа.Все данные должны быть получены из конечных узлов, поэтому количество запросов данных каждый раз одинаково;
Поместите картинку, чтобы понять более четко, B дерево
В+ дерево
На основе дерева B+ каждый узел хранит больше ключевых слов, в дереве меньше уровней, поэтому данные запроса выполняются быстрее, а все данные ключевых слов находятся в листовых узлах, поэтому количество поисков в каждый момент времени одинаково, а скорость запросов выше, чем B-деревья более стабильны. Кроме того, листовые узлы дерева B+ связаны с узлами пост-порядка, что очень полезно для поиска по диапазонам.
Кластерные и федеративные индексы
В механизме хранения InnoDB первичный ключ используется в качестве индекса для организации данных. В механизме хранения InnoDB каждая таблица имеет первичный ключ.Если при создании таблицы не отображается определенный первичный ключ, механизм хранения InnoDB выберет или создаст первичный ключ следующим образом.
-
Сначала определите, есть ли в таблице непустой уникальный индекс, если да, то столбец является первичным ключом
-
Если вышеуказанные условия не выполняются, механизм хранения InnoDB автоматически создает 6-байтовый указатель в качестве индекса.
-
Если имеется несколько ненулевых уникальных индексов, механизм хранения InnoDB выберет первый ненулевой уникальный индекс, определенный при создании таблицы, в качестве первичного ключа.
Если есть следующие данные, идентификатор пользователя является первичным ключом (1, tom), (2, mike), (3, sam), (4, lisa), (5, li), тогда данные сохраняются как это, рисунок 1
Предположим, теперь мы строим индекс имени пользователя. Как существует индекс имени пользователя? фигура 2
Данные конечного узла индекса имени пользователя хранят первичный ключ, поэтому, когда мы запускаем следующую инструкцию sql
select * from table where name ="sam"
скопировать код
Процесс такой, сначала найти соответствующий первичный ключ по индексу имени, а затем найти соответствующую запись в дереве B+, установленном при построении таблицы по соответствующему первичному ключу, то есть сначала найти его на рисунке 1, а затем найти его на рисунке 2.
Кластеризованный индекс: физический порядок строк данных совпадает с логическим порядком значений столбца (обычно это столбец первичного ключа) Таблица может иметь только один кластеризованный индекс. На рисунке 1 используется кластеризованный индекс.
Некластеризованный индекс: Определение: Логический порядок индекса в этом индексе отличается от физического порядка хранения строки диска, и таблица может иметь несколько некластеризованных индексов. На рисунке 2 используется некластеризованный индекс.
Наконец, давайте поговорим о совместном индексе.Совместный индекс относится к индексации нескольких столбцов в таблице. Создано следующим образом:
CREATE TABLE `t` ( `a` int(10), `b` int(10), PRIMARY KEY (`a`), KEY `idx_a_b` (`a`,`b`)) ENGINE=InnoDB;
скопировать код
Совместный индекс также является деревом B+.Разница в том, что количество ключевых значений объединенного индекса не равно 1, а больше или равно 2. Дерево B+ множественных значений ключа хранится следующим образом
Вы можете видеть, что значения ключей отсортированы, в приведенном выше примере (1, 1) (1, 2) (2, 1) (2, 4) (3, 1) (3, 2) данные в соответствии с (а, б) хранятся в порядке.
Следовательно, для запроса выберите * из таблицы, где a = xxx и b = xxx, очевидно, что можно использовать совместный индекс (a, b). Для одного столбца запрос выбирает * из таблицы, где a = xxx, также может использоваться индекс (a, b). Но для запроса выберите * из таблицы, где b = xxx для столбца b, этот индекс дерева B+ нельзя использовать. Можно обнаружить, что значение b на листовом узле равно 1, 2, 1, 4, 1, 2, что, очевидно, не отсортировано, поэтому запрос столбца b не может использовать индекс (a, b)
Адаптивный хэш-индекс
Механизм хранения InnoDB отслеживает запросы для различных страниц индекса в таблице. Если замечено, что построение хэш-индекса может привести к повышению скорости, то при построении хэш-индекса, называемого адаптивным хэш-индексом, администратор базы данных не может вмешиваться в процесс построения хеш-индекса, а может только включить или отключить адаптивный хэш-индекс. показатель
В базе данных обычно используется метод деления и хеширования, то есть берется остаток от деления k на m и сопоставляется ключевое слово k с одним из m слотов, то есть хэш-функция имеет вид h(k) = k mod m , когда возникает конфликт, то есть два ключевых слова могут быть сопоставлены с одним и тем же слотом, и используется метод ссылки, то есть конфликтующие ключевые слова сохраняются в виде связанного списка, аналогичного HashMap
После того, как хэш-индекс установлен для горячих данных, поиск по дереву B+ опускается, что может значительно повысить производительность службы.Адаптивный хэш-индекс очень быстр для поиска типов словарей, таких как выбор * из таблицы где id=xxx, но для поиска по диапазону это бессильно