代码之家  ›  专栏  ›  技术社区  ›  BlackWasp

将标识列的int与bigint进行比较时出现意外的性能结果

  •  4
  • BlackWasp  · 技术社区  · 17 年前

    我被要求使用sql server 2008执行性能测试。作为其中的一部分,我将使用int和bigints比较标识列作为pks的速度。我有一个简单的例程,为每种类型和插入速度创建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。

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

    4 回复  |  直到 15 年前
        1
  •  1
  •   khutch    16 年前

    要更进一步,请对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测试运行得更快。

    我从中得到的结论是,无论您向空表中抛出什么,都可以很快地将记录插入到空表中。性能的影响,即表上的其他索引,当表已经有很多数据时插入行,等等,可能是一个更重要的考虑因素。

        2
  •  1
  •   b w    15 年前

    服务器1 -在SQL 2005 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快, 但与我所看到的不同点都不一样。

        3
  •  0
  •   Stefan Steinegger    17 年前

    只是猜测一下:你有没有试过先测试bigint,然后再测试int?数据库服务器喜欢把东西保存在内存中以优化类似的操作…

        4
  •  0
  •   shaw    16 年前

    我在我的sql2008上试过了。内景需要14秒。bigint需要18秒。