NULL в MySQL (производительность и хранилище)

StackOverflow https://stackoverflow.com/questions/229179

  •  04-07-2019
  •  | 
  •  

Вопрос

Что именно значение null влияет на производительность и хранилище (пространство) в MySQL?

Например:

ТИНЬИНТ:1 байт tinyint с null 1 байт + как -то хранит нуль?

Это было полезно?

Решение

Это зависит от того, какой механизм хранения вы используете.

В формате 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

РЕДАКТИРОВАТЬ:

Биты NULL являются частью заголовков строк, и вы не можете их добавлять.

Единственный способ, с помощью которого я могу представить, что NULL-ы улучшают производительность, — это то, что в InnoDB страница данных может поместиться в большее количество строк, если строки содержат NULL-значения.Таким образом, ваши буферы InnoDB могут быть более эффективными.

Но я был бы очень удивлён, если бы на практике это дало значительный выигрыш в производительности.Беспокойство о влиянии NULL на производительность относится к сфере микрооптимизации.Вам следует сосредоточить свое внимание на другом, на тех областях, которые приносят большую отдачу от вложенных средств.Например, добавление правильно выбранных индексов или увеличение объема кэша базы данных.

Другие советы

Ответ Билла хорош, но немного устарел.Применяется использование одного или двух байтов для хранения NULL. только в формат строки InnoDB REDUNDANT.Начиная с MySQL 5.0.3 InnoDB использует КОМПАКТНЫЙ формат строки, который использует только один бит для хранения NULL (конечно, один байт — это минимум), поэтому:

Пространство, необходимое для NULL = ПОТОЛОК(N/8) байт где N — количество столбцов NULL в строке.

  • 0 NULL = 0 байт
  • 1–8 НУЛЕЙ = 1 байт
  • 9–16 НУЛИ = 2 байта
  • 17–24 НУЛИ = 3 байта
  • и т. д...

Согласно официальному сайту MySQL о COMPACT vs REDUNDANT:

Компактный формат строк уменьшает пространство для хранения строк примерно на 20% за счет увеличения использования ЦП для некоторых операций.Если ваша рабочая нагрузка является типичной и ограничена частотой попаданий в кэш и скоростью диска, компактный формат, вероятно, будет быстрее.

Преимущество использования NULLS перед пустыми строками или нулями:

  • 1 NULL требует 1 байт
  • 1 пустая строка требует 1 байт (при условии VARCHAR)
  • Для 1 нуля требуется 4 байта (при условии, что INT)

Вы начинаете видеть экономию здесь:

  • 8 NULL требуют 1 байт
  • 8 пустых строк требуют 8 байтов
  • 8 нулей требуют 32 байта.

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

Еще:https://dev.mysql.com/doc/refman/5.7/en/innodb-physical-record.html

Я бы согласился с Биллом Карвином, хотя и добавил бы: эти советы по MySQL.Номер 11 конкретно посвящен этому:

Прежде всего, спросите себя, есть ли какая-либо разница между пустым строковым значением и пустым строковым значением.значение NULL (для полей INT:0 против.НУЛЕВОЙ).Если нет причин использовать оба значения, вам не нужно поле NULL.(Знаете ли вы, что Oracle считает NULL и пустую строку одним и тем же?)

Столбцы NULL требуют дополнительного места и могут усложнить операторы сравнения.Просто избегайте их, когда можете.Однако я понимаю, что у некоторых людей могут быть очень конкретные причины иметь значения NULL, что не всегда плохо.

С другой стороны, я по-прежнему использую значение NULL в таблицах, в которых нет множества строк, главным образом потому, что мне нравится логика выражения NOT NULL.

ОбновлятьВозвращаясь к этому позже, я бы добавил, что лично мне не нравится использовать в базе данных 0 вместо 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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top