Имеет ли смысл жертва размером ради производительности?

Здравствуйте,
имеется таблица следующего вида:
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 *  TABLE: Accounts information
 *  Contains accounts list with common individual information
 *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
DROP TABLE IF EXISTS `{fDBNAME}`.`{tUSER_INFO}`{;}
CREATE TABLE IF NOT EXISTS `{fDBNAME}`.`{tUSER_INFO}`
(
`hand` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT	COMMENT 'Account handle',								# * Field size: 4 bytes
...
`lang` CHAR( 8  ) NOT NULL DEFAULT ''	COMMENT 'Account translation language',								# * Field size: 8 bytes
`zone` CHAR( 8  ) NOT NULL DEFAULT ''	COMMENT 'Account custom time zone',								# * Field size: 8 bytes
`html` CHAR( 16 ) NOT NULL DEFAULT ''	COMMENT 'Account html output template name',							# * Field size: 16 bytes
`name` CHAR( 32 ) NOT NULL DEFAULT ''	COMMENT 'Account authorization username',							# * Field size: 32 bytes
`pass` CHAR( 40 ) NOT NULL DEFAULT ''	COMMENT 'Account authorization password hash',							# * Field size: 40 bytes
`info` CHAR( 32 ) NOT NULL DEFAULT ''	COMMENT 'Account information checksum value',							# * Field size: 32 bytes

PRIMARY KEY ( `hand`, `name` )
)
ENGINE=MyISAM CHARACTER SET `{fDBCHAR}` COLLATE `{fDBCHAR}_bin` ROW_FORMAT=FIXED INSERT_METHOD=FIRST COMMENT='Accounts information'{;}

§1. Как видно из кода — это таблица, хранящая самые основные сведения о каждом зарегистрированном пользователе. Приведена она не полностью, дабы не перегружать ненужной информацией. При ближайшем рассмотрении становится понятно, что поле `name` служит для хранения имени пользователя.

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

§3. Таким образом, логично предположить дефиницию поля имени пользователя вида
`name` VARCHAR( 32 ) NOT NULL DEFAULT ''	# * Field size: 6..33 bytes
В таком случае каждая запись в таблице будет иметь плавающий размер, зависящий от значения поля `name` каждой записи, что в свою очередь означает: "ROW_FORMAT=DYNAMIC".

§4. Есть предположение, что пожертвовав максимум 27 байт на запись ( 33-6=27 ) — в редких случаях, в большинстве и того меньше, дефиницию поля имени пользователя можно изменить, сделав размерность статичной, а именно:
`name` CHAR( 32 ) NOT NULL DEFAULT ''	# * Field size: 32 bytes
А это, в свою очередь, позволит "ROW_FORMAT=FIXED".

Вопрос:
Имеет ли эта затея практический смысл, каковы плюсы и минусы?
А если более конкретно — стоит ли фиксированный формат записи 27 байт на запись?

Спасибо.
  • Вопрос задан
  • 2263 просмотра
Решения вопроса 1
alexclear
@alexclear
A cat
Я не очень понимаю, какую именно задачу Вы пытаетесь решить.
Уменьшить размер данных на диске? Так важен не он, а размер индексов.
Вы ищете по этому полю? Ищете строгим соответствием? Если LIKE 'prefix%' не используете - посчитайте хэш строки, запишите в отдельный столбец и ищете запросом вида SELECT ... WHERE t.hash=hash(?) AND t.name=?
Будет работать индекс по хэшу - а он компактнее, чем индекс по всей строке.
Но, вообще, я бы не стал этим заморачиваться, не убедившись, что с производительностью именно в этом месте есть проблемы.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Melkij
@Melkij
PostgreSQL DBA
ENGINE=MyISAM

Производительность и табличная блокировка на любой чих? Вообще-то, это взаимоисключающие вещи.

CHAR( 8 ) # * Field size: 8 bytes
VARCHAR( 32 ) # Field size: 6..33 bytes

Без указания кодировки эти вычисления неверны. В скобках указывается количество символов, количество занимаемых байт зависит от кодировки.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы