Mysql: индексы и порядок строк в таблице - PullRequest
1 голос
/ 03 августа 2020

Шаг 1:

Я создаю простую таблицу.

CREATE TABLE `indexs`.`table_one` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45) NULL,
  PRIMARY KEY (`id`));

Шаг 2:

Я делаю две вставки в эту таблицу.

insert into table_one (name) values ("B");
insert into table_one (name) values ("A");

Шаг 3:

Делаю select, получаю таблицу, записи в которой упорядочены по id.

SELECT * FROM table_one;

results select

This is the expected result, because in mysql the primary key is a clustered index, therefore the data will be physically ordered by it.

Now the part I don't understand.

Step 4:

I am creating an index on the name column.

CREATE INDEX index_name ON table_one(name)

I repeat step 3 again, but I get a different result. The lines are now ordered according to the name column.

результаты выбрать после создания индекса

Почему это происходит? почему порядок строк в таблице меняется в соответствии с новым индексом в столбце name, потому что, насколько я понимаю, в mysql первичный ключ является единственным кластеризованным индексом, а все индексы, созданные дополнительно, являются вторичными.

Ответы [ 2 ]

3 голосов
/ 03 августа 2020

Делаю select, получаю таблицу, записи в которой упорядочены по id. [...] Это ожидаемый результат, потому что в mysql первичный ключ является кластеризованным индексом, поэтому данные будут физически упорядочены им.

Существует некоторое недопонимание концепции здесь.

Строки таблицы не имеют внутреннего упорядочения: они представляют неупорядоченный набор строк. Хотя кластеризованный индекс обеспечивает физическое упорядочение данных в хранилище, он не гарантирует порядок, в котором строки возвращаются запросом select.

Если вы хотите, чтобы результаты запроса были упорядочены, тогда используйте предложение order by. Без такого предложения порядок строк будет undefined : база данных может возвращать результаты в любом порядке, и не гарантируется, что результаты будут согласованными при последовательном выполнении одного и того же запроса.

select * from table_one order by id;
select * from table_one order by name;
2 голосов
/ 03 августа 2020

(больше всего объясняет GMB)

Почему это происходит? почему порядок строк в таблице изменяется в соответствии с новым индексом в столбце name

Используйте EXPLAIN SELECT ... - это может дать представление о том, что я собираюсь предложить.

Вы добавили INDEX(name). В InnoDB столбцы PRIMARY KEY прикреплены к концу каждого вторичного индекса. Таким образом, это фактически BTree, упорядоченное по (name,id) и содержащее только эти столбцы.

Теперь Оптимизатор может свободно извлекать данные из индекса, поскольку он имеет все, что вы просили (идентификатор и имя). (Этот индекс называется «покрывающим».)

Поскольку вы не указали ORDER BY, порядок набора результатов действителен (см. Обсуждение GMB).

Мораль рассказ: Если хотите заказать, укажите ORDER BY. (Оптимизатор достаточно умен, чтобы «не делать дополнительной работы», если он видит, как предоставить данные без сортировки.

Дальнейший эксперимент: добавьте еще один столбец в таблицу, но не меняйте индексы. Теперь вы обнаружите, что SELECT * FROM t заказывается иначе, чем SELECT id, name FROM t. Думаю, я дал вам достаточно подсказок, чтобы предсказать эту разницу, если нет, спросите.

...