web-dev-qa-db-ja.com

10進データ型(MySQL / Postgres)を使用してパフォーマンスに影響はありますか

整数データ型と浮動小数点データ型がどのように格納されるかを理解しています。また、10進数データ型の可変長は、文字列のように格納されることを意味していると思います。

これは、decimalデータ型を使用してそれらを検索するときのパフォーマンスのオーバーヘッドを意味しますか?

21
wobbily_col

Pavelはそれを正しく理解しています。少し説明したいと思います。

浮動小数点または固定小数点オフセット整数と比較した場合のパフォーマンスへの影響を意味すると仮定すると(つまり、1000分の1セントを整数として格納)、はい、パフォーマンスへの影響は非常に大きくなります。 PostgreSQL、およびMySQLのサウンドにより、DECIMAL/NUMERICを2進化10進数で格納します。この形式は、数字をテキストとして保存するよりもコンパクトですが、操作するのはまだ非常に効率的ではありません。

データベースで多くの計算を行わない場合、影響は、整数または浮動小数点と比較して、BCDに必要なストレージスペースが大きくなるため、行が広くなり、スキャンが遅くなり、インデックスが大きくなります。bでの比較演算ツリーインデックスの検索も低速ですが、他の理由ですでにCPUにバインドされている場合を除いて、問題にはなりません。

データベース内のDECIMAL/NUMERIC値を使用して多くの計算を行っている場合、パフォーマンスが実際に低下する可能性があります。 Pgは特定のクエリに対して複数のCPUを使用できないため、これは少なくともPostgreSQLでは特に顕著です。数値で除算と乗算、より複雑な計算、集計などの膨大な処理を行っている場合は、floatまたはintegerデータ型を使用する場合には決してそうではない状況で、CPUに縛られていることに気づき始めることができます。これは、OLAPに似た(分析)ワークロード、およびロードまたは抽出(ETL)中のレポートまたはデータ変換で特に顕著です。

isパフォーマンスへの影響(ワークロードによって無視できるものから非常に大きなものまで変化する)があるにもかかわらず、通常はnumeric/decimalを使用する必要があります。タスクに適切なタイプ-つまり、非常に高い範囲の値を格納する必要がある場合や、丸め誤差が許容できない場合。

ときどき、bigintと固定小数点のオフセットを使用する手間がかかる価値がありますが、それは不格好で柔軟性に欠けます。代わりに浮動小数点を使用することは、通貨などの浮動小数点値を確実に処理するためのすべての課題があるため、正解となることはほとんどありません。

(ところで、私はいくつかの新しいIntel CPUとIBMのPower 7範囲のCPUにIEEE 754 10進浮動小数点のハードウェアサポートが含まれていることに非常に興奮しています。これがローエンドCPUで利用可能になれば、データベースにとって大きな勝利になるでしょう。 。)

24
Craig Ringer

10進数型(Postgresの数値型)の影響は、使用方法によって異なります。典型的なOLTPの場合、この影響はそれほど大きくない可能性があります。OLAPの場合、比較的高い可能性があります。このアプリケーションでは、数値を含む大きな列での集計は、タイプは倍精度。

現在のCPUは強力ですが、それでもルールです-正確な数値または非常に高い数値が必要な場合にのみ数値を使用する必要があります。それ以外の場合は、floatまたはdouble精度タイプを使用します。

9
Pavel Stehule

正解です。固定小数点データは( packed BCD )文字列として格納されます。

これがパフォーマンスにどの程度影響するかは、次のようなさまざまな要因によって異なります。

  1. クエリは列のインデックスを利用しますか?

  2. CPUは IntelのBCDオペコード などを介してハードウェアでBCD操作を実行できますか?

  3. OSハーネスハードウェアは、ライブラリ関数を介してサポートしますか?

全体として、パフォーマンスへの影響は、直面する可能性のある他の要因に比べるとごくわずかです。したがって、心配する必要はありません。 「時期尚早な最適化がすべての悪の根源である」とクヌースの格言を覚えておいてください。

3
eggyal

10進データ型の可変長は、文字列のように格納されることを意味していると思います。

MySqlドキュメントから取得 here

文書は言う

mySQL 5.0.3以降、DECIMALカラムの値は、数字または符号文字ごとに1バイトを必要とする文字列として表されなくなりました。代わりに、9桁の10進数を4バイトにパックするバイナリ形式が使用されます。 DECIMALストレージ形式へのこの変更により、ストレージ要件も変更されます。各値の整数部と小数部の格納要件は、個別に決定されます。 9桁の倍数ごとに4バイトが必要で、残りの桁には4バイトの一部が必要です。

2
Rahul