#mysql #database #indexing #b-tree #clustered-index
Вопрос:
Я понимаю, что в конечном узле кластеризованного индекса запись таблицы хранится вместе, скажем, с первичным ключом.
Но я обнаружил, что в некоторых статьях указано, что первичный ключ хранится с адресом блока реальной записи вместо записи реальной таблицы.
Не могли бы вы сказать мне, что правильно?
Комментарии:
1. Насколько я понимаю, индекс for
clustered
хранится в файле таблицы. Если нет, то создается отдельный индексный файл. (они приводят MyISAM в качестве примера)2. Привет @bato3 У MyISAM нет кластеризованного индекса
3. Да, именно это я и хотел написать. Этого MyISAM нет
clustered
, и там всегда создавался отдельный файл для индекса. Я предлагаю провести эксперимент и посмотреть, создаст ли он дополнительный файл для InnoDB.CONSTRAINT pk PRIMARY KEY NONCLUSTERED (id)
4. На этот вопрос, вероятно, можно найти лучшие ответы в dba.stackexchange.com .
Ответ №1:
Будьте осторожны с тем, что вы читаете. Убедитесь, что в статье говорится о «MySQL» и его главном «движке» «InnoDB».
первичный ключ хранится с адресом блока реальной записи вместо реальной записи таблицы.
Несколько целых строк хранятся в каждом конечном узле (блоке) B -дерева данных. Это BTree упорядочено по PRIMARY KEY
, которое (очевидно) является частью строки.
Единственные «адреса блоков» — это ссылки, которые есть у вас на обеих ваших диаграммах.
Я голосую за вашу диаграмму номер 2 с такими оговорками:
- Существует строка из 4 столбцов с id = 6 и другие столбцы Джеймса, 37 лет, Лос-Анджелес.
- Строка с идентификатором=15 показана не полностью. То есть вы не учли остальные 3 столбца.
«Блок» имеет размер 16 КБ и может содержать от 1 до нескольких сотен строк, в зависимости от
- размер строк,
- были ли удалены строки, оставив «свободное» место,
- и т.д.
(100 строк на блок либо для данных, либо для индекса — это простое эмпирическое правило.)
Комментарии:
1. Спасибо за ваш ответ, я следил за тем, как найти ответ в контексте mysql и innodb.
Ответ №2:
В контексте mysql и innodb, с официальной страницы mysql https://dev.mysql.com/doc/refman/8.0/en/innodb-index-types.html
Каждая таблица InnoDB имеет специальный индекс, называемый кластеризованным индексом, в котором хранятся данные строк.
Если таблица большая, архитектура кластеризованного индекса часто экономит операцию дискового ввода-вывода по сравнению с организациями хранения, которые хранят данные строк, используя страницу, отличную от индексной записи.
Основываясь на приведенных выше фактах, особенно на номере 2, я считаю, что # 2 является правильным. С моей стороны причинами являются (1) сохранение одноразового ввода-вывода. Если конечный узел сохранит адрес страницы, будет еще один раз ввода-вывода для извлечения записи.
(2) большая удобство обслуживания. Если произошло разделение страницы и конечный узел сохранил только адрес страницы, кластеризованному индексу будет сложно обновить адрес страницы данных записи.
Однако причина, по которой я думаю, что # 1 имеет точки, заключается в том, что сохранение только адреса дешевле, чем сохранение всей строки данных записи и, следовательно, сохранение большего индекса.
Комментарии:
1. Есть несколько запросов, которые будут выполняться быстрее с # 1. Но (по моему опыту) таких случаев меньшинство. То есть InnoDB принял «правильное» проектное решение.