Что быстрее: char(1) или tinyint(1)? Зачем?

МОЯ ПЛАТФОРМА:

PHP и MySQL

МОЯ СИТУАЦИЯ:

Я столкнулся с ситуацией, когда мне нужно сохранить значение для выбора пользователя в одном из моих столбцов таблицы. Теперь мои варианты будут:

  1. Либо объявите столбец как char(1) и сохраните значение как "y" или "n"
  2. Или объявите Столбец как tinyint(1) и сохраните значение как 1 или 0
  3. Этот столбец, объявленный таким образом, также может быть проиндексирован для использования в приложении.

МОИ ВОПРОСЫ:

Итак, я хотел знать, какой из двух указанных выше типов:

  1. Привод к более быстрой скорости запросов при доступе к этому столбцу (для простоты давайте не будем смешивать другие запросы или обращаться к другим столбцам, пожалуйста).

  2. Является ли самый эффективный способ хранения и доступа к данным и почему?

  3. Как меняется скорость доступа, если столбцы индексируются, а когда нет?

Насколько я понимаю, поскольку char(1) и tinyint(1) занимают только 1 байт, в этом случае не будет проблем с объемом памяти. Тогда то, что останется, это скорость доступа. Насколько я знаю, числовая индексация быстрее и эффективнее, чем что-либо еще. Но дело здесь трудно решить, я думаю. Определенно хотел бы услышать ваш опыт по этому вопросу.

Заранее спасибо.

8 ответов

Решение

Я думаю, что вы должны создать столбец с ENUM('n','y'), Mysql хранит этот тип оптимальным образом. Это также поможет вам хранить только допустимые значения в поле.

Вы также можете сделать его более дружелюбным к человеку ENUM('no','yes') без влияния на производительность. Потому что строки 'no' а также 'yes' хранятся только один раз за ENUM определение. Mysql хранит только индекс значения в строке.

Также обратите внимание на сортировку по ENUM колонка:

Значения ENUM сортируются в соответствии с порядком, в котором элементы перечисления перечислены в спецификации столбца. (Другими словами, значения ENUM сортируются в соответствии с их порядковыми номерами.) Например, "a" сортирует перед "b" для ENUM("a", "b"), но "b" сортирует перед "a" для ENUM("б", "а").

                       Rate insert tinyint(1) insert char(1) insert enum('y', 'n')
insert tinyint(1)     207/s                --            -1%                  -20%
insert char(1)        210/s                1%             --                  -19%
insert enum('y', 'n') 259/s               25%            23%                    --
                       Rate insert char(1) insert tinyint(1) insert enum('y', 'n')
insert char(1)        221/s             --               -1%                  -13%
insert tinyint(1)     222/s             1%                --                  -13%
insert enum('y', 'n') 254/s            15%               14%                    --
                       Rate insert tinyint(1) insert char(1) insert enum('y', 'n')
insert tinyint(1)     234/s                --            -3%                   -5%
insert char(1)        242/s                3%             --                   -2%
insert enum('y', 'n') 248/s                6%             2%                    --
                       Rate insert enum('y', 'n') insert tinyint(1) insert char(1)
insert enum('y', 'n') 189/s                    --               -6%           -19%
insert tinyint(1)     201/s                    7%                --           -14%
insert char(1)        234/s                   24%               16%             --
                       Rate insert char(1) insert enum('y', 'n') insert tinyint(1)
insert char(1)        204/s             --                   -4%               -8%
insert enum('y', 'n') 213/s             4%                    --               -4%
insert tinyint(1)     222/s             9%                    4%                --

кажется, что, по большей части, enum('y', 'n') быстрее вставить в.

                       Rate select char(1) select tinyint(1) select enum('y', 'n')
select char(1)        188/s             --               -7%                   -8%
select tinyint(1)     203/s             8%                --                   -1%
select enum('y', 'n') 204/s             9%                1%                    --
                       Rate select char(1) select tinyint(1) select enum('y', 'n')
select char(1)        178/s             --              -25%                  -27%
select tinyint(1)     236/s            33%                --                   -3%
select enum('y', 'n') 244/s            37%                3%                    --
                       Rate select char(1) select tinyint(1) select enum('y', 'n')
select char(1)        183/s             --              -16%                  -21%
select tinyint(1)     219/s            20%                --                   -6%
select enum('y', 'n') 233/s            27%                6%                    --
                       Rate select tinyint(1) select char(1) select enum('y', 'n')
select tinyint(1)     217/s                --            -1%                   -4%
select char(1)        221/s                1%             --                   -2%
select enum('y', 'n') 226/s                4%             2%                    --
                       Rate select char(1) select tinyint(1) select enum('y', 'n')
select char(1)        179/s             --              -14%                  -20%
select tinyint(1)     208/s            17%                --                   -7%
select enum('y', 'n') 224/s            25%                7%                    --

Выбор также, кажется, enum, Код можно найти здесь

Использование tinyint является более стандартной практикой и позволит вам более легко проверить значение поля.

// Using tinyint 0 and 1, you can do this:
if($row['admin']) {
    // user is admin
}

// Using char y and n, you will have to do this:
if($row['admin'] == 'y') {
    // user is admin
}

Я не специалист по внутренней работе MySQL, но интуитивно чувствую, что извлечение и сортировка целочисленных полей быстрее, чем символьных полей (я просто чувствую, что 'a' > 'z' - это больше работы, чем 0 > 1) и кажется гораздо более знакомым с вычислительной точки зрения, в которой 0 и 1 являются стандартными флагами включения / выключения. Таким образом, хранилище для целых чисел кажется лучше, оно приятнее и его проще использовать в логике кода. 0/1 - явный победитель для меня.

Вы также можете заметить, что, в некоторой степени, это официальная позиция MySQL также из их документации:

BOOL, BOOLEAN: Эти типы являются синонимами для TINYINT(1). Нулевое значение считается ложным. Ненулевые значения считаются истинными.

Если MySQL отождествляет TINYINT (1) с BOOLEAN, это похоже на путь.

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

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

CHAR может занимать более одного байта, в зависимости от выбранного набора символов и параметров таблицы. Некоторые символы могут занимать три байта для кодирования, поэтому MySQL иногда резервирует это пространство, даже если вы используете только y а также n,

Они оба будут настолько близки, что это не имеет значения. Если вы чувствуете необходимость задать этот вопрос на SO, вы чрезмерно оптимизируете. Используйте тот, который имеет наиболее логичный смысл.

Хотя я догадываюсь, что индекс в TINYINT будет быстрее, чем индекс в CHAR(1) из-за того, что нет затрат на обработку строк (сортировка, пробелы и т. Д.), У меня нет никаких фактов, чтобы поддержи это. Я думаю, что нет существенной разницы в производительности, о которой стоит беспокоиться.

Однако, поскольку вы используете PHP, сохранение в виде TINYINT имеет гораздо больше смысла. Использование значений 1/0 эквивалентно использованию true а также false, даже когда они возвращаются как строки в PHP, и могут быть обработаны как таковые. Вы можете просто сделать if ($record['field']) с вашими результатами в виде логической проверки, вместо того, чтобы постоянно конвертировать между 'y' и 'n'.

Если вы укажете типы BOOL или же BOOLEAN как тип столбца при создании таблицы в MySQL, он создает тип столбца как TINYINT(1), Предположительно, это быстрее из двух.

Документация

Также:

Мы намерены реализовать полную обработку булевых типов в соответствии со стандартным SQL в будущем выпуске MySQL.

 TINYINT    1 Byte
CHAR(M)     M Bytes, 0 <= M <= 255

есть ли другое?

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