NULL в MySQL (производительность и хранение) - PullRequest
67 голосов
/ 23 октября 2008

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

Например:

TINYINT: 1 байт TINYINT с NULL 1 байт + каким-то образом хранит NULL?

Ответы [ 4 ]

92 голосов
/ 23 октября 2008

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

В формате 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 на производительность лежит в области микрооптимизации. Вы должны сосредоточить свое внимание в другом месте, в областях, которые дают больший удар для доллара. Например, добавление правильно выбранных индексов или увеличение выделения кэша базы данных.

29 голосов
/ 18 августа 2015

Ответ Билла хорош, но немного устарел. Использование одного или двух байтов для хранения значения NULL применяется только к формату строк InnoDB REDUNDANT. Поскольку MySQL 5.0.3 InnoDB использует COMPACT формат строки, который использует только один бит для хранения NULL (конечно, один байт является минимальным), следовательно:

Необходимое пространство для NULL = CEILING (N / 8) байтов , где N - количество столбцов NULL в строке.

  • 0 NULLS = 0 байтов
  • 1 - 8 NULLS = 1 байт
  • 9 - 16 NULLS = 2 байта
  • 17 - 24 NULLS = 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

6 голосов
/ 09 марта 2015

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

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

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

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

Обновление Возвращаясь к этому позже, я бы добавил, что лично мне не нравится использовать 0 вместо NULL в базе данных, и я не рекомендую это. Это может легко привести к множеству ложных срабатываний в вашем приложении, если вы не будете осторожны.

1 голос
/ 19 мая 2013

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

...