Есть ли производительность с использованием десятичных типов данных (MySQL/Postgres)

Я понимаю, как хранятся типы данных с целым числом и с плавающей точкой, и я предполагаю, что переменная длина десятичных типов данных означает, что она больше хранится как строка.

Это связано с чрезмерной нагрузкой на производительность при использовании десятичного типа данных и поиска по ним?

Ответ 1

У Павла это совершенно правильно, я просто хотел бы немного объяснить.

Предполагая, что вы имеете в виду влияние производительности по сравнению с целым числом с плавающей запятой или целым числом с фиксированной запятой (т.е. с сохранением тысяч единиц в процентах как целое число): Да, это очень сильно влияет на производительность. PostgreSQL, а также звуками вещей MySQL, сохраните DECIMAL/NUMERIC в двоично-кодированном десятичном значении. Этот формат более компактен, чем хранение цифр в виде текста, но с ним все еще не очень эффективно работать.

Если вы не делаете много вычислений в базе данных, влияние ограничено большим объемом памяти, требуемым для BCD, по сравнению с целым или с плавающей запятой, и, следовательно, более широкими рядами и более медленными сканированиями, большими индексами и т.д. Сравнение операции в поисковых индексах b-дерева также медленнее, но недостаточно, чтобы иметь значение, если вы уже не привязаны к CPU по какой-либо другой причине.

Если вы выполняете множество вычислений с помощью значений DECIMAL/NUMERIC в базе данных, производительность может действительно пострадать. Это особенно заметно, по крайней мере, в PostgreSQL, поскольку Pg не может использовать более одного CPU для любого заданного запроса. Если вы делаете огромную совокупность деления и умножения, более сложные математические вычисления, агрегацию и т.д. На численных вычислениях, вы можете начать находить CPU-привязку в ситуациях, когда вы никогда не будете использовать тип данных с плавающей точкой или целочисленным типом. Это особенно заметно в OLAP-подобной (аналитической) рабочей нагрузке, а также при представлении отчетов или преобразовании данных во время загрузки или извлечения (ETL).

Несмотря на то, что влияние производительности (которое зависит от рабочей нагрузки от незначительного до довольно большого), вы обычно должны использовать NUMERIC/DECIMAL, когда это наиболее подходящий тип для вашей задачи - то есть когда очень высокий значения диапазона должны быть сохранены и/или ошибка округления неприемлема.

Иногда это стоит того, чтобы использовать смещение bigint и фиксированной точки, но это неуклюже и негибко. Использование плавающей запятой вместо этого очень редко является правильным ответом из-за всех проблем надежной работы с значениями с плавающей запятой для таких вещей, как валюта.

(Кстати, я очень взволнован, что некоторые новые процессоры Intel и процессоры IBM Power 7 включают аппаратную поддержку десятичной плавающей точки IEEE 754. Если это когда-нибудь станет доступным в нижних CPU, это будет огромная выиграть для баз данных.)

Ответ 2

Влияние десятичного типа (числовой тип в Postgres) зависит от использования. Для типичного OLTP это влияние не может быть значительным - поскольку OLAP может быть относительно высоким. В нашем приложении агрегация на больших столбцах с числовым числом в несколько раз медленнее, чем для двойной точности типа.

Несмотря на то, что текущий процессор силен, по-прежнему остается правило - вы должны использовать цифру только тогда, когда вам нужны точные цифры или очень высокие цифры. В другом месте используется тип float или double precision.

Ответ 3

Вы правы: данные фиксированной точки сохраняются как (упакованная BCD) строка.

В какой степени это влияет на производительность, зависит от ряда факторов, которые включают:

  • У запросов используется индекс в столбце?

  • Может ли процессор выполнять операции BCD на оборудовании, например, через Коды операций Intel BCD?

  • Поддерживает ли аппаратное обеспечение аппаратного обеспечения ОС через функции библиотеки?

В целом, любое влияние на производительность может быть довольно незначительным по сравнению с другими факторами, с которыми вы можете столкнуться: так что не беспокойтесь об этом. Помните принцип Кнута, "преждевременная оптимизация - это корень всего зла".

Ответ 4

Я предполагаю, что переменная длина десятичных типов данных означает это хранится больше как строка.

Взято из документа MySql здесь

В документе говорится:

с MySQL 5.0.3 Значения для столбцов DECIMAL больше не представлены в виде строк, которые требуется 1 байт на символ или знак. Вместо этого двоичный формат используется, который упаковывает девять десятичных цифр в 4 байта. Это изменение Формат хранения DECIMAL также изменяет требования к хранению. требования к хранению для целочисленных и дробных частей каждого значение определяются отдельно. Каждой кратной девяти цифрам требуется 4 байта, а любые оставшиеся цифры требуют некоторой доли 4 байта.