Notez que je ne parle pas d'un index clusterisé par rapport à un index non-cluster, je veux dire un index clusterisé comparé à aucun index pour l'insertion de performance.
J'ai vu beaucoup de liens comme ci-dessous dit que, un index clusterisé a de meilleures performances contre aucun index même pour l'opération d'insertion, en raison de IAM / PFS / bitmap / …, mais avec mes tests, semble aucun indice n'est plus rapide que l'index de cluster, quel est le problème?
Suppression d'une key primaire (index clusterisé) pour augmenter les performances d'insertion http://support.microsoft.com/kb/297861
mes scripts de test:
------------------------------------------- --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
Pour toute opération d'insertion, aucun index n'est plus rapide qu'avec un index . Lorsque vous avez un index sur une table, après l'insertion de chaque ligne, le server de database doit allouer une reference à la ligne dans l'index bitmap ou le référentiel d'index, qui est un surcoût pour le server. Cela affecte le nombre de lignes insérées par seconde.