Sql server 将标识列的INT与BIGINT进行比较时出现意外的性能结果

Sql server 将标识列的INT与BIGINT进行比较时出现意外的性能结果,sql-server,performance,Sql Server,Performance,我被要求使用SQLServer2008执行性能测试。作为其中的一部分,我将比较标识列作为PKs使用int和BIGINTs的速度。我有一个简单的例程,为每种类型创建100000行,并计算插入速度。脚本如下所示: SET NOCOUNT ON CREATE TABLE TestData ( PK INT IDENTITY PRIMARY KEY, Dummy INT ) DECLARE @Rows INT DECLARE @Start DATETIME SE

我被要求使用SQLServer2008执行性能测试。作为其中的一部分,我将比较标识列作为PKs使用int和BIGINTs的速度。我有一个简单的例程,为每种类型创建100000行,并计算插入速度。脚本如下所示:

SET NOCOUNT ON

CREATE TABLE TestData
(
    PK      INT IDENTITY PRIMARY KEY,
    Dummy   INT
)

DECLARE @Rows   INT
DECLARE @Start  DATETIME

SET @Rows = 100000
SET @Start = GETDATE()

WHILE @Rows > 0
BEGIN
    INSERT INTO TestData (Dummy) VALUES (@Rows)
    SET @Rows = @Rows - 1
END

SELECT @Start, GETDATE(), DATEDIFF(MS, @Start, GETDATE())

DROP TABLE TestData
为了测试BIGINT标识,我使用了一个稍加修改的版本:

SET NOCOUNT ON

CREATE TABLE TestData
(
    PK      BIGINT IDENTITY PRIMARY KEY,
    Dummy   INT
)

DECLARE @Rows   INT
DECLARE @Start  DATETIME

SET @Rows = 100000
SET @Start = GETDATE()

WHILE @Rows > 0
BEGIN
    INSERT INTO TestData (Dummy) VALUES (@Rows)
    SET @Rows = @Rows - 1
END

SELECT @Start, GETDATE(), DATEDIFF(MS, @Start, GETDATE())

DROP TABLE TestData
令我惊讶的是,BIGINT版本的运行速度明显快于INT版本。我测试套件上的INT版本大约需要30秒,BIGINT大约需要25秒。假设测试套件有一个64位处理器。但是,它运行的是32位Windows和32位SQL Server 2008


其他人是否可以重新创建、否认、确认或质疑结果,或者指出我是否遗漏了什么?

只是一个猜测:你有没有试过先测试BIGINT,然后再测试INT?数据库服务器喜欢将内容保存在内存中,以优化类似的操作…

我在我的SQL2008上尝试过。整数需要14秒。BIGINT需要18秒。

要更进一步,请对VARCHAR执行相同的操作,例如:

SET NOCOUNT ON

CREATE TABLE TestData
(
    PK          VARCHAR(8) PRIMARY KEY,
    Dummy       INT
)

DECLARE @Rows   INT
DECLARE @Start  DATETIME

SET @Rows = 100000
SET @Start = GETDATE()

WHILE @Rows > 0
BEGIN
    INSERT INTO TestData (PK, Dummy) VALUES (CONVERT(VARCHAR(8), @Rows), @Rows)
    SET @Rows = @Rows - 1
END

SELECT @Start, GETDATE(), DATEDIFF(MS, @Start, GETDATE())

DROP TABLE TestData
我希望这会慢得多,因为脚本正在确定“identity”列,并且存在字符串转换。另外,我使用VARCHAR(8)将字节数与bigint匹配。然而,在我的测试中,这比上面的INT测试运行得更快


我从中得出的结论是,无论您对空表进行什么操作,将记录插入到空表中都会非常快。未来性能的影响,即表上的其他索引、在表已经有大量数据时插入行等,可能是一个更重要的考虑因素。

Server1-on SQL2005 SP3 64位。。。我只是试了一下(INT然后BIGINT),得到了2.9秒和2.6秒。然后把行数增加到500000,我得到了15.2秒和15.3秒

  • 超过500K INT/BIGINT运行:14.0/14.6s;14.0/15.3s;和14.7/15.3s。所以INT比BIGINT快5.8%
  • 将命令反转为BIGINT/INT:15.4/13.8s;15.3/15.4s;和12.9/12.7s。INT在这里快4%
服务器2-在SQL2000 SP4 EE上

  • INT/BIGINT:13.7/10.9s;10.4/13.9s;9.9/10.2s。INT的速度提高了2.9%
  • 然后切换到BIGINT/INT:10.2/13.3s;10.2/10.1s;和11.2/10.0s。BIGINT的速度提高了5.7%

基本上,INT通常比BIGINT快,但并不总是比BIGINT快,但与我在运行过程中看到的差异相差不大。

在这两个过程之前,还有其他过程运行过吗?哪一个是第一个运行的?它也是完全可重复的。我可以一个接一个地运行脚本,它们在时间上的变化只有几百毫秒,但是BIGINT总是快四五秒左右。打开“设置统计时间”,打开“设置统计IO”?@BlackWasp:刚刚在Vista x64/SQL Express 2008 x64上试过,没有任何区别(两个时间均为46秒,可重复).OTOH,Express版本的性能可能会受到限制,因此这可能不是一个现实的结果。我只是在与Express相同的测试盒上进行了尝试,结果与我以前的测试结果相同。不,尝试了两种方法,在两种方法之间重新启动服务。您是否尝试过并发现相反的结果?不,我直到现在才尝试,这只是一个猜测。我可以在工作中尝试。我在SQLServer2005上尝试过,它在完全相同的时间运行。我认为其中一些原因是数据的绝对大小导致了额外的页面创建。这也取决于您的页面大小,这是可配置的,IIRC。您已将其增加了1/3d(每行8个字节到12个)