Недавно я написал базу данных, и многие друзья оставили сообщения с вопросами о базовой реализации индекса MySQL.为什么
спроектирован таким образом».
Вопрос 1. Зачем базам данных создавать индексы?
В библиотеке есть книги мощностью 1000 Вт. Чтобы найти "Дорогу архитектора", проверяйте их одну за другой. Когда вы хотите их проверить?
Итак, библиотекарь разработал свод правил:
(1) Классы истории расположены на первом этаже, классы литературы — на втором этаже, а классы информационных технологий — на третьем этаже…
(2) Категория ИТ, которая делится на категорию программного обеспечения, категорию оборудования...
(3) Категория программного обеспечения, а затем сортировка по названию книги...
Чтобы найти книгу быстро.
По аналогии, в базе хранится 1000 Вт данных, чтобы найти записи с name="shenjian", проверяйте их одну за другой, когда вы их найдете?
Итак, естьпоказатель,用于提升数据库的查找速度
.
Вопрос 2. Хэш (hash) быстрее, чем tree (дерево), зачем структуру индекса оформлять в виде дерева?
ускорить поиск数据结构
, существует два распространенных типа:
(1)хэш, таких как HashMap, средняя временная сложность запроса/вставки/изменения/удаления составляет O(1);
(2)Дерево, таких как сбалансированное двоичное дерево поиска, средняя временная сложность запроса/вставки/изменения/удаления составляет O(lg(n));
можно увидеть,不管是读请求,还是写请求
,哈希类型的索引,都要比树型的索引更快一些
, тогда почему структура индекса должна быть оформлена в виде дерева?
*画外音:80%的同学,面试都答不出来。*
Индекс спроектирован как дерево, которое связано с требованиями SQL.
Для такого А.однострочный запросТребования SQL:
выберите * из t, где имя = «shenjian»;
Это правда, что хэш-индекс быстрее, потому что за раз запрашивается только одна запись.
*画外音:所以,如果业务需求都是单行访问,例如passport,确实可以使用哈希索引。*
Но дляСортировать запросТребования SQL:
- Группировка: группировать по
- Сортировать: упорядочить по
- Сравните:
- …
хэшТип индекс, момент сложности будет退化为O(n)
,итип дереваиз"有序
"функция, по-прежнему способная保持O(log(n))
высокой эффективности.
Любое оформление, отклоняющееся от требований, является хулиганством.
Еще одно слово,InnoDB并不支持哈希索引
.
Вопрос 3. Почему индексы баз данных используют деревья B+?
Чтобы сохранить целостность системы знаний, кратко представлены несколько видов деревьев.
Первый тип: бинарное дерево поиска
Двоичное дерево поиска, как показано на рисунке выше, является наиболее известной структурой данных, поэтому я не буду ее здесь представлять.Почему он не подходит для использования в качестве индекса базы данных?
(1) Когда объем данных велик,树的高度会比较高
, когда объем данных большой, запрос будет выполняться медленнее;
(2)每个节点只存储一个记
запись, что может привести к множеству дисковых операций ввода-вывода для одного запроса;
*画外音:这个树经常出现在大学课本里,所以最为大家所熟知。*
Второй: B-дерево
B-дерево, как показано на рисунке выше, характеризуется:
(1) это уже не бинарный поиск, а поиск m fork;
(2) Листовые узлы и нелистовые узлы хранят данные;
(3) Обход по порядку, можно получить все узлы;
*画外音,实在不想介绍这个特性:非根节点包含的关键字个数j满足,(┌m/2┐)-1 <= j <= m-1,节点分裂时要满足这个条件。*
B-дерево было создано как структура данных для реализации индексов, потому что оно прекрасно использует «принцип локальности».
Что такое принцип локальности?
Логика принципа локальности такова:
(1) Блоки чтения и записи памяти, чтение и запись диска происходит медленно и намного медленнее;
(2)диск читать вперед: Диск читается и пишется и不是按需读取,而是按页预读
, одна страница данных будет считываться за раз, и каждый раз будет загружаться больше данных.Если данные, которые будут считаны в будущем, находятся на этой странице, это может избежать будущих операций ввода-вывода на диск и повысить эффективность;
Голос за кадром: Обычно страница данных имеет размер 4K.
(3)принцип локальности: дизайн программного обеспечения должен стараться следовать «концентрации чтения данных» и «использовать данные, данные рядом с ними будут использоваться с высокой вероятностью», чтобы упреждающее чтение с диска могло полностью улучшить дисковый ввод-вывод;
Почему B-дерево подходит для индексации?
(1) Так как этоm分叉
, высота может быть значительно уменьшена;
(2)每个节点可以存储j个记录
, если размер узла установлен равным размеру страницы, например 4 КБ, функция упреждающего чтения может быть полностью использована, а дисковый ввод-вывод может быть значительно уменьшен;
Третий тип: B+ дерево
Дерево B+, как показано на рисунке выше, по-прежнему является m-арным деревом поиска.некоторые улучшения:
(1) Нелистовые узлы больше не хранят данные,数据只存储在同一层的叶子节点上
;
*画外音:B+树中根到每一个节点的路径长度一样,而B树不是这样。*
(2) Между листьями добавляется связанный список для получения всех узлов, и обход по порядку больше не требуется;
Эти улучшения придают деревьям B+ лучшие свойства, чем деревья B:
(1) Поиск диапазона, после определения минимума и максимума, промежуточный конечный узел представляет собой набор результатов без промежуточного возврата;
*画外音:范围查询在SQL中用得很多,这是B+树比B树最大的优势。*
(2) Листовой узел хранит фактическую строку записи, а строка записи хранится относительно компактно, что подходит для хранения больших данных на диске; нелистовой узел хранит PK записи, который используется для ускорения запросов и подходит для хранения памяти;
(3) Если нелистовой узел не хранит фактическую запись, а хранит только КЛЮЧ записи, то в случае той же памяти дерево B+ может хранить больше индексов;
Наконец, для количественной оценки**为什么m叉的B+树比二叉搜索树的高度大大大大降低?**
Вероятно, вычислить:
(1) Принцип локальности, размер узла установлен в одну страницу, одна страница 4K, при условии, что КЛЮЧ имеет 8 байт, узел может хранить 500 КЛЮЧЕЙ, то есть j=500
(2) m-арное дерево, примерно m/2
(3) Тогда:
Одно дерево: узел 1, 1*500 KEY, размер 4К
Двухуровневое дерево: 1000 узлов, 1000Ключи 500=50 Вт, размер 10004K=4M
Трехуровневое дерево: 10001000 узлов, 10001000500=500 миллионов ключей, размер 10001000*4K=4G
*画外音:额,帮忙看下有没有算错。*
Видно, что для хранения большого количества данных (500 миллионов) не требуется очень большая глубина дерева (высота 3), а индекс не занимает слишком много памяти (4G).
Суммировать
- Индекс базы данных используется для ускорения запросов
- Хотя хэш-индекс равен O(1), а индекс дерева равен O(log(n)), в SQL есть много «упорядоченных» требований, поэтому база данных использует индекс дерева.
- InnoDB не поддерживает хеш-индексы.
- Чтение данных чтениеИдея: прочитайте чтение и запись диска не требуется, но Pre-Read Page по странице, страница будет читаться с данными, каждая дополнительная нагрузка данных, чтобы уменьшить будущее диска IO
- принцип локальности: разработка программного обеспечения должна стараться следовать «концентрации чтения данных» и «использовать данные, большая вероятность будет использовать их окрестности», чтобы чтение с диска могло значительно увеличить дисковый ввод-вывод.
- Наиболее часто используемое дерево B+ для индексов баз данных:
(1) Он очень подходит для хранения на диске и может в полной мере использовать принцип локальности и упреждающего чтения с диска;
(2) очень низкая высота дерева, способная хранить большой объем данных;
(3) Память, занимаемая самим индексом, очень мала;
(4) Он может хорошо поддерживать одноточечный запрос, запрос диапазона и упорядоченный запрос;
Хотя все они являются деревьями B+, в следующей главе мы поговорим о различиях в реализации индексов между InnoDB и MyISAM.