Являются ли столбцы, которые не являются индексами, отсортированы на диске вместе с индексом?

8

Являются ли столбцы, которые не являются индексами, отсортированы на диске вместе с индексом в MySQL, в MyISAM и InnoDB?

Неправильная мысль, которую я начал писать:

Я думаю, что, вероятно, нет, так как они не проиндексированы; если бы они были отсортированы, это означало бы, что они являются индексами.

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

Чтобы пояснить, я говорю: это было бы полезно сделать выбор диапазонов строк, которые стоят рядом, вместе по своим индексам, быстрее. Например, если я хочу select * where id >1000 and id<2000(могут быть ошибки в синтаксисе MySQL, я не очень хорошо это знаю), тогда сам столбец id можно быстро прочитать с диска, поскольку, вероятно, его ячейки от 1000 до 2000 остаются вместе на физическом диске. , Но другой контент столбца, соответствующий идентификатору 1000-2000, может быть записан в разных местах на физическом диске. Если они также отсортированы, они будут читаться быстрее. Я думаю, возможно MySQL автоматически сортирует эти столбцы на физическом диске для выполнения таких операций.

Они сортируются в других типах баз данных (PostgreSQL и т. Д.)?

27 декабря. Я вижу из двух ответов, что в случае кластерного индекса / первичного ключа сами простые строки не сортируются на физическом диске (как я думал, это может / может быть), и даже кластерный индекс не отсортировано, если это b-дерево, я прочитал о b-дереве и вижу, что его узлы, как я понимаю, остаются в произвольных местах на диске.

qdinar
источник

Ответы:

9

Они могут быть отсортированы в некоторых случаях. Индекс сортировки обычно называется ключом кластеризации . Если это так, то вся таблица хранится внутри такого индекса (обычно в какой-то структуре B-дерева).

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

MyISAM использует структуру кучи , где каждая строка идентифицируется смещением (своего рода индексом массива ) в файле данных. Каждый индекс затем содержит индексированные столбцы для каждой строки, отсортированные в правильном порядке и с номером смещения, чтобы найти реальную строку. Это означает, что доступ к строке по любому индексу означает определение правого узла (узлов) в индексе (B-дерево) и последующее считывание правого смещения из файла данных (может произойти случайное обращение к другой части диска). ).

InnoDB использует кластеризацию по первичному ключу (или, если он не определен, используется первый непустой уникальный ключ или добавляется внутренний столбец автоинкрементации - поэтому строки всегда каким-то образом сортируются). В таком случае доступ по первичному ключу является «прямым», когда найдено правильное значение, у вас есть вся строка под рукой, нет необходимости делать второе чтение. С другой стороны, вторичные индексы не могут хранить смещение, как в MyISAM (потому что B-дерево само себя динамически перебалансирует, поэтому смещение конкретной строки может измениться в любое время), и вместо этого они хранят значения первичного ключа строки - поэтому доступ по вторичному ключу означает два поиска B-дерева в InnoDB.

MS SQL Server предлагает возможность сделать первичный ключ (или другой индекс) кластеризованным или некластеризованным, так что вы можете выбирать между кучей (ни один индекс не кластеризован) и древовидной структурой (один индекс кластеризован). Все другие некластеризованные индексы хранят специальные значения (RowID) в случае кучи или значения кластеризованных ключей строки в случае CI.

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

TokuDB (сторонний движок MySQL / MariaDB) может использовать несколько ключей кластеризации в одной таблице - фактически он поддерживает несколько копий таблицы, каждый из которых отсортирован по-разному. Это идет со штрафом на записи, но TokuDB утверждает, что использует что-то, что они называют фрактальными индексами, что должно сделать этот штраф довольно маленьким.

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

jkavalik
источник
5

Краткий и простой ответ для баз данных в целом: нет, физический порядок строк в таблице обычно не такой, как в каком-либо индексе этой таблицы.

В общем (я говорю в целом, потому что есть особые случаи, когда это не так), таблица и индекс - это две разные физические структуры на диске. Обычные RDBM хранят данные таким образом, чтобы значения из одной строки таблицы (не столбца ) находились рядом на диске; сами строки не хранятся в каком-либо определенном порядке. Записи индекса, с другой стороны, хранятся в порядке; типичный индекс b-дерева содержит отсортированные значения индексированных столбцов (но не других столбцов!) и своего рода указатель на расположение всей строки в таблице, которая, как я уже говорил, представляет собой отдельную физическую структуру на диске.

При этом есть особые случаи. Например, MySQL InnoDB хранит фактические строки данных в структуре, подобной индексу. Индекс, по которому строки помещаются в такую ​​«таблицу индекса», обычно является первичным ключом таблицы; и такой индекс называется кластеризованным индексом . Но, конечно, таблица InnoDB может иметь другие индексы, и порядок строк (то есть столбцы строк, которые включены в соответствующий индекс) в этих индексах не имеет ничего общего с порядком строк в самой таблице.

zgguy
источник