主键的SQL Server BIGINT或DECIMAL(18,0)

Ada*_*ler 11 sql sql-server performance types sql-server-2005

我们有一个SQL Server 2005数据库,我们想要提高批量删除/插入/选择的性能,我注意到它decimal(18,0)用于主键.我知道这将给我们带来更多的价值,bigint但希望它可能是一个快速的胜利,并且应该通过我的计算能够持续数百万年的增长.

我在.net docs中看到小数点需要16个字节而不是long所需的8个字节,但是在SQL Server中,它看起来像bigint 需要8个字节,decimal(18,0)只占用5个字节 - 也可以看到select DATALENGTH(max(id)) from table.它是否正确?

有没有其他原因bigint可能会更慢或我应该坚持decimal(18,0)

Bri*_*ter 21

你用bigint得到这个范围:

-2^63 to 2^63-1 

also known as roughly:

-9.2 x 10^18 to 9.2 x 10^18
Run Code Online (Sandbox Code Playgroud)

你得到这个带小数(18,0)的范围:

-10^18 to 10^18
Run Code Online (Sandbox Code Playgroud)

十进制:每精度存储字节数

Precision    Storage Bytes
1-9:         5
10-19:       9
20-28:       13
29-38:       17
Run Code Online (Sandbox Code Playgroud)

整数类型和存储字节

integer type    Storage Bytes
bigint          8
int             4
smallint        2
tinyint         1
Run Code Online (Sandbox Code Playgroud)

思考

您的问题中发布的两个示例实际上产生了几乎相同数量的唯一值.

此外,无论您的选择如何,您都不会看到显着的性能变化,但如果您开始使用程序员期望整数的小数,您将看到团队中其他程序员的效率发生变化.这是一个小问题.

要解决您的具体问题,如果您想要更大的范围,请使用十进制(38,0).这给你:

-10^38 to 10^38
Run Code Online (Sandbox Code Playgroud)

如果您担心速度,请使用将持续软件生命周期的最低精度.

如果您没有以纳秒为单位测量时间,那么选择最适合您的程序员心态的选项以及您希望拥有一组很长的数字.

参考


gbn*_*gbn 9

在计算字节数之前,DATALENGTH正在转换为varchar.所以你的最大值<100000.

用这个可以证明9个字节.sys.columns有一个max_length列(十进制是固定长度所以它总是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
Run Code Online (Sandbox Code Playgroud)

由于遗留原因,decimal(18, 0)在使用SQL Server 2000添加bigint之前,它经常被用作"64位整数"的代理.

decimal(18, 0)并且bigint在范围上大致相同:根据文档,十进制是9个字节的一个字节

最重要的是,普通整数将比小数快一些(可能不可测量).如果说,如果预计明年或5年将有超过40亿行,那么表现应该是重要的.如果没有,那就用吧int

  • bigint适合64位机器上的单个寄存器,而9字节小数则不适合.如果我们谈论的是在整个地方使用的主键,我预计这将是非常昂贵的. (3认同)