Следует ли избегать использования среды в mysql?
Я наткнулся на комментарий к следующему блогу, который рекомендует не использовать mediaint:
Не используйте [24-битный INT], даже в MySQL. Его немой, и его медленный, и код, который его реализует, - это ужасный ужас.
4294967295 и MySQL INT (20) Синтаксические удары
Ответ на stackoverflow также отмечает, что SQL Server, Postgres и DB2 не поддерживают среду.
В чем разница между tinyint, smallint, mediumint, bigint и int в MySQL?
Следует ли избегать использования среды или продолжать использовать ее в тех случаях, когда она лучше всего отражает данные, которые я храню?
Ответы
Ответ 1
InnoDB сохраняет MEDIUMINT в виде трех байтов. Но когда MySQL должен делать какие-либо вычисления, три байта MEDIUMINT преобразуются в восемь байтов unsigned long int (я полагаю, никто не запускает MySQL на 32 бита в настоящее время).
Есть плюсы и минусы, но вы понимаете, что "Его немой, и его медленный, и код, который его реализует, - это обходный ужас", рассуждение не является техническим, не так ли?
Я бы сказал, что MEDIUMINT имеет смысл, когда размер данных на диске имеет решающее значение. Т.е. когда в таблице так много записей, что даже одна байтовая разность (4 байта INT против 3 байт MEDIUMINT) означает много. Это довольно редкий случай, но возможно.
mach_read_from_3 и mach_read_from_4 - примитивы, которые InnoDB использует для чтения чисел из записей InnoDB, схожи. Они оба возвращают ulint. Бьюсь об заклад, вы не заметите разницы в любой рабочей нагрузке.
Просто взгляните на код:
ulint
mach_read_from_3(
/*=============*/
const byte* b) /*!< in: pointer to 3 bytes */
{
ut_ad(b);
return( ((ulint)(b[0]) << 16)
| ((ulint)(b[1]) << 8)
| (ulint)(b[2])
);
}
Считаете ли вы, что это намного медленнее, чем это?
ulint
mach_read_from_4(
/*=============*/
const byte* b) /*!< in: pointer to four bytes */
{
ut_ad(b);
return( ((ulint)(b[0]) << 24)
| ((ulint)(b[1]) << 16)
| ((ulint)(b[2]) << 8)
| (ulint)(b[3])
);
}
Ответ 2
В великой схеме вещей выборка - большая стоимость. Простые функции, выражения и, тем более, форматы данных незначительны в том, сколько времени занимает запрос.
С другой стороны, если ваш набор данных слишком велик, чтобы оставаться в кэше, накладные расходы ввода-вывода для получения строк (строк) еще более значительны. Грубое эмпирическое правило гласит, что не кэшированная строка занимает в 10 раз больше, чем кешированная. Следовательно, сжатие набора данных (например, использование меньшего *INT
) может дать вам огромное преимущество в производительности.
Этот аргумент яблок ...INT
, FLOAT
против DOUBLE
, DECIMAL(m,n)
, DATETIME(n)
и т.д. (Для [VAR]CHAR/BINARY(...)
и TEXT/BLOB
требуется другое обсуждение. )
Для тех, кто имеет фон на языке ассемблера...
- Таблица, вероятно, будет иметь смесь чисел и строк, тем самым препятствуя попыткам "выровнять" значения.
- MySQL всегда обрабатывал различные аппаратные средства (большие/мало-endian, 16/32/64-бит) с двоичной совместимостью. Обратите внимание на то, как код @akuzminsky предоставил возможность избежать выравнивания и устранения ошибок. И это позволяет компилятору иметь дело с 32-разрядными проблемами, если аппаратное обеспечение составляет всего 16 бит.
- Код для проверки для особых случаев, вероятно, перевешивает просто пишущий общий код.
- Мы говорим, как правило, менее 1% от общего времени обработки строк.
Следовательно, единственным нормальным способом написания кода является работа на уровне байта и игнорирование размера регистра и принятие всех значений неверно выровненных.
Для оптимизации в порядке важности:
- Подсчитайте диски. Прикосновение к диску в подавляющем большинстве является самой дорогостоящей частью запроса.
- Подсчитайте количество затронутых строк. Поиск строки (через BTree и т.д.) Занимает некоторый процессор. Но, заметьте, очень мало установок связаны с CPU; те, которые имеют тенденцию иметь плохие показатели. (Правило большого пальца: обычно в строке индекса или индекса индекса InnoDB содержится 100 строк).
- Только теперь разбор строки входит в игру.
Правило большого пальца: если предварительная оптимизация не позволяет (с помощью огибающей конверта) получить 10% -ное улучшение, не тратьте на него свое время. Вместо этого найдите какое-то большее улучшение. Например, индексы и сводные таблицы часто предоставляют 10x (не только 10%).