web-dev-qa-db-ja.com

主キーのSQLServer BIGINTまたはDECIMAL(18,0)

一括削除/挿入/選択のパフォーマンスを向上させたいSQLServer 2005データベースがあり、主キーにdecimal(18,0)を使用していることに気付きました。これにより、bigintよりもはるかに多くの値が得られることを理解していますが、これがすぐに成功し、私の計算では何百万年もの成長が続くことを期待していました。

.netで見る docs 小数はlongで必要な8バイトではなく16バイトを取りますが、SQLServerではbigint8バイトを取ります のように見えますが、 decimal(18,0)5バイト -のみを取ります。これはselect DATALENGTH(max(id)) from tableからもわかります。これは正しいです?

bigintが遅くなる理由は他にありますか、それともdecimal(18,0)に固執する必要がありますか?

12
Adam Butler

DATALENGTHは、バイトをカウントする前にvarcharにキャストしています。したがって、最大値は<100000です。

これで9バイトを証明できます。 sys.columns max_length列があります(10進数は固定長であるため、特に要求する前は常に9バイトです)

_CREATE TABLE dbo.foo (bar decimal(18,0))
GO
SELECT * FROM sys.columns WHERE object_id = OBJECT_ID('foo') 
GO
DROP TABLE dbo.foo
GO
_

従来の理由から、SQL Server 2000でbigintが追加される前は、decimal(18, 0)が「64ビット整数」の代理として使用されることがよくありました。

decimal(18, 0)bigintの範囲はほぼ同じです。10進数は9バイトで1バイト多くなりますドキュメントによる

その上、単純な整数は10進数よりも部分的に(おそらく測定できない)高速になります。つまり、来年または5年に40億行を超えると予想される場合は、パフォーマンスが重要になるはずです。そうでない場合は、intを使用してください

9
gbn

bigintでこの範囲を取得します:

-2^63 to 2^63-1 

also known as roughly:

-9.2 x 10^18 to 9.2 x 10^18

この範囲はdecimal(18,0)で取得できます:

-10^18 to 10^18

10進数:精度あたりのストレージバイト数

Precision    Storage Bytes
1-9:         5
10-19:       9
20-28:       13
29-38:       17

整数型とストレージバイト

integer type    Storage Bytes
bigint          8
int             4
smallint        2
tinyint         1

考え

質問に投稿された2つの例は、実際には実質的に同じ量の一意の値を生成します。

また、選択に関係なくパフォーマンスに大きな変化は見られませんが、プログラマーが整数を期待している場所で小数を使い始めると、チームの他のプログラマーの効率に変化が見られます。これはマイナーな点です。

特定の問題に対処するために、より広い範囲が必要な場合は、Decimal(38,0)を使用します。これはあなたに与えます:

-10^38 to 10^38

速度が気になる場合は、ソフトウェアの寿命が続く最小の精度を使用してください。

ナノ秒単位で時間を測定していない場合は、プログラマーの考え方と非常に長い数値のセットが必要な場合に最適なオプションを選択してください。

参照

21
Brian Webster