Лучшая производительность в MYSQL 8 между BIT или BOOL для поиска

Я использую MySQL 8.0 CE. У меня есть атрибут, в котором я хочу сохранить статус TRUE или FALSE, и я хочу, чтобы он занимал как можно меньше места.

Прочитав ответы на этот вопрос: MySQL: Наименьший тип данных для одного бита и документация MySQL Тип битового значения - BIT и Целочисленные типы (точное значение), я понимаю, что на уровне хранения лучше использовать BIT(1) потому что BOOL на самом деле является TINYINT(1) и поэтому использует полный 1 байт.

На уровне хранилища ясно, что BIT(1) — лучший вариант, но на уровне производительности при поиске истинного или ложного?

Если я правильно понимаю, BIT будет хранить 1 или 0, а BOOL хранит TRUE или FALSE.

Эта разница заключается в том, что при поиске между обеими возможностями один из типов лучше оптимизирован для этого?

Спасибо.

Это пахнет преждевременной оптимизацией

devlin carnate 16.09.2022 19:54

Что ты имеешь в виду?

SideTest 17.09.2022 08:33

@SideTest — Девлин имеет в виду обычную практику программистов, которые заранее тратят время на оптимизацию вещей, которые не будут иметь достаточного значения, чтобы оправдать потраченное время.

Rick James 17.09.2022 19:32

@devlincarnate - А, хорошо! Да! это возможно. Но я люблю докапываться до сути, даже если потом не использую :) К тому же, это действительно хобби, так что время относительно. В реальной жизни со сроками я бы не смог сделать так много, хотя правда и то, что я люблю максимально оптимизировать вещи.

SideTest 18.09.2022 10:22
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
1
4
70
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

BIT(1) также требует минимум 1 байт, поэтому вы не экономите место по сравнению с BOOL/TINYINT. Оба занимают 1 байт.

Говоря с разработчиками MySQL, они обычно вздрагивают, когда я упоминаю тип данных BIT. Он полон известных ошибок и, вероятно, не обнаруженных ошибок. Внутренний код плохо изучен. Они сказали мне просто использовать TINYINT.

Кстати, в MySQL нет настоящего BOOL типа. BOOL — это просто псевдоним для TINYINT(1), и нет истинного или ложного значения. Значение «ложь» — это буквально целое число 0, а значение «истина» — это целое число 1. Другими словами, вы можете SUM() столбец, который предположительно является логическим, и вы получите целочисленную сумму, равную количеству строк, в которых столбец "истинный". Это несовместимо со стандартным SQL (нет смысла использовать SUM() для логического столбца), но именно так BOOL реализовано в MySQL.

В другом направлении NULL действует как ложь, и любое ненулевое значение является «истиной».

Rick James 16.09.2022 23:34

@RickJames Я бы не сказал, что NULL ложно, потому что NOT NULL неправда.

Bill Karwin 17.09.2022 01:19

Какая логика в существовании BIT(1), BOOL/TINYINT(1), если все они занимают 1 байт? В любом случае, видя, что все они занимают одно и то же место и что, как говорит @RickJames, нет заметного улучшения производительности, я выслушаю вас и воспользуюсь TINYINT(1).

SideTest 17.09.2022 08:33

@SideTest, MySQL реализует строковый тип данных BIT как часть стандарта SQL, поэтому клиенты ожидают, что он будет поддерживаться. Если вы храните более длинные битовые строки, они эффективно используют байты. Но они выделяют целый байт за раз. Таким образом, строка из N бит использует (N+7)/8 байт.

Bill Karwin 17.09.2022 14:53

Вы имеете в виду, что в стандарте SQL BIT(1) будет занимать только 1 бит, а не байт? Другое дело, что потом он будет сгруппирован по байтам.

SideTest 18.09.2022 10:22

Нет, в стандарте указано только, что BIT — это тип данных, семантика которого позволяет вызывающей стороне адресовать отдельные биты. Это не диктует, как это должно храниться. Я говорю о том, как это реализует MySQL.

Bill Karwin 18.09.2022 16:15

Учитывая, что в mysql логическое значение такое же, как и tinyint(1). Тем не менее, логическое значение всегда использует 1 байт на столбец, но бит (n) будет использовать столько байтов, сколько необходимо для хранения заданного количества битов. BIT экономит место, однако я бы использовал логическое значение, потому что оно упрощает работу в тот момент, когда вы хотите запросить базу данных. в терминах вы можете иметь значения, отличные от 0 или 1, если вы не будете осторожны. Чтобы избежать этого, вы можете использовать псевдонимы TRUE и FALSE.

(В дополнение к тому, что говорит Билл...)

У меня есть практическое правило: «Если предварительная оценка не предполагает улучшения хотя бы на 10%, перейдите к какой-либо другой оптимизации». Соедините это с тем фактом, что даже если однобитовое логическое значение сократит длину строки на 7 бит, это, вероятно, даст экономию менее 1%. Итак, я иду дальше.

OTOH, если у вас много логических значений, рассмотрите тип данных SET, который может обрабатывать до 64 логических значений в 8 байтах или меньше. Но это довольно неуклюже. То же самое и с 64-битным BIGINT UNSIGNED вместе со сдвигом и логическими операторами (<<, & и т. д.).

Если вам нужно INDEX одно или несколько логических значений, забудьте об этом. Единственный случай, когда индексирование работает, — это составной (многостолбцовый) индекс, где один из столбцов [эффективно] TINYINT NOT NULL

Да, я тоже смотрел на тип set и рассмотрю его в будущем, но для этого случая мне просто нужны два варианта.

SideTest 17.09.2022 08:36

@SideTest - Похоже на мои правила RoT.

Rick James 17.09.2022 19:31

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