Подтвердить что ты не робот

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

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

PHP и mySQL

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

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

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

МОИ ВОПРОСЫ:

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

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

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

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

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

Спасибо заранее.

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

                       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. Код может быть найден здесь

Ответ 3

Использование 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), и, похоже, он гораздо более знаком с вычислительной точки зрения, в которой 0s и 1s являются стандартными флагами включения/выключения. Таким образом, хранение целых чисел, по-видимому, лучше, оно приятнее и легче использовать в логике кода. 0/1 - явный победитель для меня.

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

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

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

Ответ 4

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

В столбцах

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

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

Ответ 5

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

Ответ 6

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

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

также:

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

Ответ 7

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

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

Ответ 8

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

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