仅在SqlServer 2008上使用聚簇索引或没有任何索引的表更好地在表上插入性能?

时间:2013-08-14 16:50:04

标签: sql-server performance insert heap clustered-index

注意,我不是在谈论针对非集群索引的聚簇索引,我的意思是聚合索引,而不是根本没有索引来插入性能。

我看到很多链接如下所述,由于IAM / PFS / bitmap / ...,聚集索引对于无插入操作具有更好的性能,但是对于我的测试,似乎没有索引比集群索引,有什么问题?

Removing a Primary Key (Clustered Index) to increase Insert performance http://support.microsoft.com/kb/297861

我的测试脚本:

-------------------------------------------
--prepare table with clustered index
CREATE TABLE [dbo].[BigTable_CI](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [BigChar] [char](4100) NOT NULL
) 
GO

CREATE CLUSTERED INDEX CIX_BigTable_CI
    ON BigTable_CI(id)
GO


ALTER TABLE [dbo].[BigTable_CI] 
ADD CONSTRAINT [DF_BigTable_BigChar_CI]  DEFAULT ('a') FOR [BigChar]
GO

CREATE PROCEDURE [dbo].[AddDataToBigTable_CI]
(@NumberOfRows bigint)    
AS
    SET NOCOUNT ON;

    DECLARE @Counter int = 0;
    DECLARE @Start   datetime = GETDATE();
    DECLARE @End     datetime;
    DECLARE @ElapsedTime int = 0; 
    DECLARE @RowsPerSecond int = 0;

    WHILE (@Counter < @NumberOfRows)
        BEGIN
           INSERT INTO dbo.BigTable_CI DEFAULT VALUES;
           SELECT @Counter += 1;
        END; 

    -- Calculate elapsed time and rows/second
    SET @End = GETDATE(); 
    SET @ElapsedTime = CONVERT(INTEGER, DATEDIFF (second, @Start, @End));
    SET @RowsPerSecond = @NumberOfRows/@ElapsedTime;

    -- Record results in local table
    INSERT INTO dbo.Results
    (StartTime, EndTime, ElapsedTime, NumberOfRows, RowsPerSecond) 
    VALUES (@Start, @End, @ElapsedTime, @NumberOfRows, @RowsPerSecond);

    RETURN;


-------------------------------------------
--prepare table without any index at all.
CREATE TABLE [dbo].[BigTable_NI](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [BigChar] [char](4100) NOT NULL
) 
GO

ALTER TABLE [dbo].[BigTable_NI] 
ADD CONSTRAINT [DF_BigTable_BigChar_NI]  DEFAULT ('a') FOR [BigChar]
GO

CREATE PROCEDURE [dbo].[AddDataToBigTable_NI]
(@NumberOfRows bigint)    
AS
    SET NOCOUNT ON;

    DECLARE @Counter int = 0;
    DECLARE @Start   datetime = GETDATE();
    DECLARE @End     datetime;
    DECLARE @ElapsedTime int = 0; 
    DECLARE @RowsPerSecond int = 0;

    WHILE (@Counter < @NumberOfRows)
        BEGIN
           INSERT INTO dbo.BigTable_NI DEFAULT VALUES;
           SELECT @Counter += 1;
        END; 

    -- Calculate elapsed time and rows/second
    SET @End = GETDATE(); 
    SET @ElapsedTime = CONVERT(INTEGER, DATEDIFF (second, @Start, @End));
    SET @RowsPerSecond = @NumberOfRows/@ElapsedTime;

    -- Record results in local table
    INSERT INTO dbo.Results
    (StartTime, EndTime, ElapsedTime, NumberOfRows, RowsPerSecond) 
    VALUES (@Start, @End, @ElapsedTime, @NumberOfRows, @RowsPerSecond);

    RETURN;   

-------------------------------------------
--prepare the results table
    create table dbo.Results 
    (
        StartTime datetime, 
        EndTime datetime, 
        ElapsedTime int, 
        NumberOfRows int, 
        RowsPerSecond int
    )

-------------------------------------------
--run scripts:
    exec [dbo].[AddDataToBigTable_NI] 1000000
    exec [dbo].[AddDataToBigTable_CI] 1000000

1 个答案:

答案 0 :(得分:0)

对于任何插入操作,索引都不比索引快。当您在表上有索引时,在插入每一行之后,数据库服务器必须分配对位图索引或索引存储库中的行的引用,这对服务器是开销。这会影响每秒插入的行数。