2011-07-27 23 views
8

バルク削除/挿入/選択のパフォーマンスを向上させるSQL Server 2005データベースがあります。主キーにはdecimal(18,0)が使用されています。私はこれがbigintよりも多くの価値を与えてくれると理解していますが、それが速い勝利であり、私の計算によって何百万年もの成長を続けなければならないことを望んでいました。私は、.NET docs小数で見る主キーのBIGINTまたはDECIMAL(18,0)

は16バイトの代わりに、long型で必要とされる8を取るが、SQL Serverでそれがbiginttake 8 bytesのように見えるがdecimal(18,0)だけ5 bytesを取る - もselect DATALENGTH(max(id)) from tableで見られるように。これは正しいです?

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

+4

あなたの場合、10進数(18,0)は9バイトではありません5 –

+0

DATALENGTH関数は5ですか? –

答えて

8

DATALENGTHはバイトをカウントする前にvarchar型にキャストされます。最大値は<100000です。

これで9バイトが証明できます。 bigint型が追加される前のsys.columnsは(それは常に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 

decimal(18, 0)は、多くの場合、「64ビット整数」の代理として使用されたMAX_LENGTH列を持っていますSQL Serverと2000

decimal(18, 0)bigintの範囲でほぼ同じである10進数は、その上で文書

どおり9バイトで1バイト以上であり、普通の整数(分数であろうおそらく測定できない)より速く、そして小数。次の年または5年間に40億以上の行があることが予想される場合は、パフォーマンスが重要であると言います。そうでない場合は、int

+3

bigintは、64ビットマシン上の単一のレジスタに適合しますが、9バイトの小数点はありません。私たちがどこかで使用されているプラ​​イマリキーについて話しているなら、私はこれがかなりコストがかかると思います。 –

20

あなたはBIGINTで、この範囲を得る:

-10^18 to 10^18 

進:

-2^63 to 2^63-1 

also known as roughly: 

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

あなたはこの小数を持つ範囲(18,0)取得ストレージバイトを精密

あたり
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つの例では、実際に一意の値のほぼ同じ量をもたらします。

また、あなたの選択にかかわらず、重要なパフォーマンスの変化は見られませんが、プログラマーが整数を期待している小数点以下を使用し始めると、チームの他のプログラマーの効率が変化します。これは小さなポイントです。

特定の問題に対処するには、範囲を広げたい場合は小数点(38,0)を使用します。

速度が心配な場合は、ソフトウェアの寿命を延ばす最小精度を使用してください。

ナノ秒単位で時間を測定していない場合は、プログラマーの考え方に適したオプションを選択し、非常に長い数字セットを使用したいと考えています。

参照