Что именно делает NULL для производительности и хранения (пробела) мудрым в MySQL?
Например:
TINYINT: 1 байт TINYINT w/NULL 1 байт + как-то хранит NULL?
Что именно делает NULL для производительности и хранения (пробела) мудрым в MySQL?
Например:
TINYINT: 1 байт TINYINT w/NULL 1 байт + как-то хранит NULL?
Это зависит от того, какой механизм хранения вы используете.
В формате MyISAM каждый заголовок строки содержит битовое поле с одним битом для каждого столбца для кодирования состояния NULL. Столбец с номером NULL по-прежнему занимает пробел, поэтому NULL не уменьшает объем памяти. См. https://dev.mysql.com/doc/internals/en/myisam-introduction.html
В InnoDB каждый столбец имеет "смещение начала поля" в заголовке строки, который представляет собой один или два байта на столбец. Высокий бит в этом начальном смещении поля включен, если столбец равен NULL. В этом случае столбец не нужно хранить вообще. Поэтому, если у вас много NULL, ваше хранилище должно быть значительно уменьшено. См. https://dev.mysql.com/doc/internals/en/innodb-field-contents.html
EDIT:
Бит NULL являются частью заголовков строк, вы не хотите их добавлять.
Единственный способ, которым я могу представить, что NULL повышает производительность, - это то, что в InnoDB страница данных может поместиться больше строк, если строки содержат NULL. Таким образом, ваши буферы InnoDB могут быть более эффективными.
Но я был бы очень удивлен, если бы это обеспечило значительное преимущество в производительности на практике. Беспокойство о влиянии NULL на производительность находится в сфере микро-оптимизации. Вы должны сосредоточить свое внимание в другом месте, в областях, которые дают больший удар для доллара. Например, добавление хорошо отобранных индексов или увеличение выделения кэша базы данных.
Ответ на ответ хороший, но немного устаревший. Использование одного или двух байтов для хранения NULL применяет только к формату строки InnoDB REDUNDANT. Поскольку MySQL 5.0.3 InnoDB использует формат строки COMPACT, который использует только один бит для хранения NULL (конечно, один байт является минимальным), поэтому:
Необходимое пространство для NULL = ПОТОЛОК (N/8) байтов, где N - количество столбцов NULL в строке.
Согласно официальному сайту MySQL о COMPACT и REDUNDANT:
Компактный формат строки уменьшает пространство для хранения строк примерно на 20% за счет увеличения использования ЦП для некоторых операций. Если ваша рабочая нагрузка является типичной, которая ограничена скоростью попадания кэш-памяти и скоростью диска, компактный формат, скорее всего, будет быстрее.
Вы начинаете видеть сбережения здесь:
С другой стороны, я предлагаю использовать NULL по пустым строкам или нулям, потому что они более организованные, портативные и требуют меньше места. Чтобы повысить производительность и сэкономить место, сосредоточьтесь на использовании правильных типов данных, индексов и запросов вместо странных трюков.
Подробнее о: https://dev.mysql.com/doc/refman/5.7/en/innodb-physical-record.html
Я согласен с Биллом Карвином, хотя я бы добавил эти советы MySQL. Номер 11 обращается к этому конкретно:
Прежде всего, спросите себя, есть ли разница между наличием пустого строкового значения и значением NULL (для полей INT: 0 или NULL). Если нет причин иметь оба, вам не нужно поле NULL. (Знаете ли вы, что Oracle считает NULL и пустую строку одной и той же?)
Столбец NULL требует дополнительного пространства, и они могут добавить сложности в ваши операторы сравнения. Просто избегайте их, когда сможете. Тем не менее, я понимаю, что некоторые люди могут иметь очень конкретные причины иметь значения NULL, что не всегда плохо.
С другой стороны, я все еще использую null для таблиц, у которых нет тонны строк, главным образом потому, что мне нравится логика, указывающая NOT NULL.
Обновление Повторяя это позже, я бы добавил, что лично мне не нравится использовать 0 вместо NULL в базе данных, и я не рекомендую его. Это может легко привести к множеству ложных срабатываний в вашем приложении, если вы не будете осторожны.
Взгляните на мое сообщение в этом разделе (короче говоря, ответ избегает NULL, если это возможно)
dev.mysql.com/doc/refman/5.0/en/is-null-optimization.html
MySQL может выполнять ту же оптимизацию на col_name IS NULL, что он может использовать для col_name = constant_value. Например, MySQL может использовать индексы и диапазоны для поиска NULL с IS NULL