Почему размер хранилища индекса таблицы больше после изменения charset с utf8mb4 на utf8? - PullRequest
0 голосов
/ 23 октября 2019

Выполнено: alter table device_msg convert to character set 'utf8' COLLATE 'utf8_unicode_ci';"

Как я ожидаю size размер данных таблицы изменится на меньший.

Но в то же время размер индекса таблицы изменится на больший?

Что происходит и почему?

ps: размер данных таблицы и размер индекса рассчитываются по параметру information_schema.TABLES


DbEngine: InnoDB

Таблица до:

CREATE TABLE `device_msg` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `sn` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
  `time` datetime(3) NOT NULL,
  `msg` json NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `device_UNIQUE` (`sn`,`time`)
) ENGINE=InnoDB AUTO_INCREMENT=62077733 DEFAULT CHARSET=utf8mb4;

Таблица после:

CREATE TABLE `device_msg` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `sn` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
  `time` datetime(3) NOT NULL,
  `msg` json NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `device_UNIQUE` (`sn`,`time`)
) ENGINE=InnoDB AUTO_INCREMENT=62077733 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;


До:

totalSize: 2.14 GB
indexSize: 282.98 MB
dataSize: 1.86 GB
avg_row_len:  297B

После

totalSize: 1.93 GB
indexSize: 413.97 MB
dataSize: 1.52 GB
avg_row_len:  260B

Если данные в information_schema.TABLES не точны,

Как правильно сделать?

Ответы [ 2 ]

1 голос
/ 24 октября 2019
  • Пространство, занятое utf8mb4, затем utf8 (при условии, что заранее не было 4-байтовых символов) одинаково, , несмотря на отображаемые числа .

  • Это ALTER требовало перестройки таблицы и индексов.

  • InnoDB структурирует данные и каждый вторичный индекс в BTrees.

  • В зависимости от порядка, в котором вы вставляете элементы в BTree, может происходить больше или меньше «разбиений по блокам».

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

Я говорю, что это было не изменение кодировки.

0 голосов
/ 23 октября 2019

Просто на мой взгляд

Как я читал на MySQL документ об ограничении.

https://dev.mysql.com/doc/refman/5.6/en/innodb-restrictions.html

По умолчанию ограничение длины префикса ключа индексаравно 767 байт

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

в случае utf8mb4, 1 символ = 4 байта, ограничение составляет около 191 символа. Таким образом, 191 символ будет добавлен в индекс, другие (255-191 = 64) символы будут усечены из индекса.

Когда вы изменяете кодировку на utf8 (в то время 1 символ = 3 байта), индексированнаяпредел станет около 255 символов. Это означает, что значение вашего столбца, все 255 символов, будет добавлено в индекс без усечения.

Количество символов, добавляемых в индекс, увеличилось с 191 до 255 символов, поэтому размер индекса также был увеличен.

...