2015-04-13 4 views
3

Мне была поставлена ​​задача повысить производительность запросов в таблице.Изменение ключа кластеризации в существующей таблице - SQL Server 2008

Первичный ключ - это GUID, который создается кодом приложения, поэтому не является последовательным, и на столе нет отдельной последовательной клавиши кластеризации.

Мое ощущение, что в качестве основного и кластеризованного ключа, являющегося основным виновником низкой производительности, является выбор несекретного GUID. Я намерен удалить кластерный индекс на GUID и добавить в качестве ключа кластера INT IDENTITY.

В таблице есть ~ 3 миллиона строк.

Лучше попробовать изменить таблицу или создать новую таблицу, скопировать на нее существующие данные, удалить старую таблицу и переименовать новую таблицу?

EDIT: Копирование 3 миллионов строк принимает очень долгое время. Будет ли снижение индекса быстрее?

EDIT 2: решил решить проблему медленного копирования с помощью аппаратного обеспечения и бросил на него 20 ядер вместо 4. Это намного быстрее, хотя и намного медленнее, чем я ожидал. Я бы оценил, что понадобится 30 минут, чтобы скопировать 3 миллиона строк.

По-прежнему оценил бы решение, хотя, поскольку это всего лишь тест, мне все же нужно сделать это на производственном сервере, я бы предпочел не использовать его дольше, чем это необходимо.

Для информации, основанной на совете от @ughai, мои настройки авторасширения теперь равны 500 МБ.

Этот вид вещей на самом деле не является моей специальностью, поэтому было бы полезно получить совет относительно того, что является лучшим способом обойти это.

Если это актуально, основная часть запросов, которые имеют место в этой таблице, не имеет объединений.

EDIT: Оригинал Таблица Schema

CREATE TABLE [dbo].[IODBTaskHistory](
    [Id] [uniqueidentifier] NOT NULL, 
    [Tag] [nvarchar](250) NULL, 
    [Type] [int] NOT NULL, 
    [SourceFilePath] [nvarchar](max) NOT NULL, 
    [DestinationFilePath] [nvarchar](max) NULL, 
    [Priority] [int] NOT NULL, 
    [State] [int] NOT NULL, 
    [SubState] [int] NOT NULL, 
    [StateDescription] [nvarchar](max) NULL, 
    [Progress] [decimal](5, 2) NOT NULL, 
    [Date_Created] [datetime] NOT NULL, 
    [Date_Queued] [datetime] NULL, 
    [Date_Started] [datetime] NULL, 
    [Date_Finished] [datetime] NULL, 
    [Date_LastUpdated] [datetime] NULL, 
    [Optional_ParentDependancyTaskId] [uniqueidentifier] NULL, 
    [Optional_isParentSuccessRequired] [bit] NULL, 
    [Transfer_ProgressBytes] [float] NULL, 
    [Transfer_SpeedCurrentBps] [float] NULL, 
    [Transfer_SpeedIntervals] [nvarchar](max) NULL, 
    [IODrone_Id] [uniqueidentifier] NULL, 
    [IODrone_Version] [nvarchar](max) NULL, 
    [Action] [int] NOT NULL, 
    [Date_TransferStarted] [datetime] NULL, 
    [Optional_NotificationEmails] [nvarchar](max) NULL, 
    [MaxRetryCount] [int] NULL, 
    [CurrentRetryCount] [int] NULL, 
    [Impersonation_Username] [nvarchar](200) NOT NULL, 
    [Impersonation_Password] [nvarchar](max) NOT NULL, 
    [AllowRewrite] [bit] NOT NULL CONSTRAINT [DF_IODBTaskHistory_AllowRewrite] DEFAULT ((0)), 
    [SubTag] [nvarchar](255) NULL, 
    [SourceLengthBytes] [bigint] NULL CONSTRAINT [DF_IODBTaskHistory_SourceLengthBytes2] DEFAULT ((0)), 
    [IODrone_Thread] [int] NULL, 
    [Date_FileSizeFetched] [datetime] NULL, 
    [Date_StornextTapeRetrievalStarted] [datetime] NULL, 
    [Date_StornextTapeRetrievalFinished] [datetime] NULL, 
    [IOServiceAddress] [nvarchar](20) NULL, 
    [LogString] [nvarchar](max) NULL, 
    [NotesString] [nvarchar](max) NULL, 
    [TX_Date] [datetime] NULL, 
    [SlowDownUpload] [bit] NULL CONSTRAINT [DF_IODBTaskHistory_SlowDownUpload] DEFAULT ((0)), 
CONSTRAINT [PK_IODBTaskHistory] PRIMARY KEY CLUSTERED 
(
    [Id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] 

назначения Таблица Схема

CREATE TABLE [dbo].[IODBTaskHistoryNew](
    [Id] [uniqueidentifier] NOT NULL, 
    [ClusterKey] [int] IDENTITY(1,1) NOT NULL, 
    [Tag] [nvarchar](250) NULL, 
    [Type] [int] NOT NULL, 
    [SourceFilePath] [nvarchar](max) NOT NULL, 
    [DestinationFilePath] [nvarchar](max) NULL, 
    [Priority] [int] NOT NULL, 
    [State] [int] NOT NULL, 
    [SubState] [int] NOT NULL, 
    [StateDescription] [nvarchar](max) NULL, 
    [Progress] [decimal](5, 2) NOT NULL, 
    [Date_Created] [datetime] NOT NULL, 
    [Date_Queued] [datetime] NULL, 
    [Date_Started] [datetime] NULL, 
    [Date_Finished] [datetime] NULL, 
    [Date_LastUpdated] [datetime] NULL, 
    [Optional_ParentDependancyTaskId] [uniqueidentifier] NULL, 
    [Optional_isParentSuccessRequired] [bit] NULL, 
    [Transfer_ProgressBytes] [float] NULL, 
    [Transfer_SpeedCurrentBps] [float] NULL, 
    [Transfer_SpeedIntervals] [nvarchar](max) NULL, 
    [IODrone_Id] [uniqueidentifier] NULL, 
    [IODrone_Version] [nvarchar](max) NULL, 
    [Action] [int] NOT NULL, 
    [Date_TransferStarted] [datetime] NULL, 
    [Optional_NotificationEmails] [nvarchar](max) NULL, 
    [MaxRetryCount] [int] NULL, 
    [CurrentRetryCount] [int] NULL, 
    [Impersonation_Username] [nvarchar](200) NOT NULL, 
    [Impersonation_Password] [nvarchar](max) NOT NULL, 
    [AllowRewrite] [bit] NOT NULL, 
    [SubTag] [nvarchar](255) NULL, 
    [SourceLengthBytes] [bigint] NULL, 
    [IODrone_Thread] [int] NULL, 
    [Date_FileSizeFetched] [datetime] NULL, 
    [Date_StornextTapeRetrievalStarted] [datetime] NULL, 
    [Date_StornextTapeRetrievalFinished] [datetime] NULL, 
    [IOServiceAddress] [nvarchar](20) NULL, 
    [LogString] [nvarchar](max) NULL, 
    [NotesString] [nvarchar](max) NULL, 
    [TX_Date] [datetime] NULL, 
    [SlowDownUpload] [bit] NULL, 
PRIMARY KEY NONCLUSTERED 
(
    [Id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY], 
UNIQUE CLUSTERED 
(
    [ClusterKey] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] 

GO 

ALTER TABLE [dbo].[IODBTaskHistoryNew] ADD CONSTRAINT [DF_IODBTaskHistory_AllowRewriteNew] DEFAULT ((0)) FOR [AllowRewrite] 
GO 

ALTER TABLE [dbo].[IODBTaskHistoryNew] ADD CONSTRAINT [DF_IODBTaskHistory_SourceLengthBytes2New] DEFAULT ((0)) FOR [SourceLengthBytes] 
GO 

ALTER TABLE [dbo].[IODBTaskHistoryNew] ADD CONSTRAINT [DF_IODBTaskHistory_SlowDownUploadNew] DEFAULT ((0)) FOR [SlowDownUpload] 
GO 

МОЯ Копировать запрос

INSERT INTO [dbo].[IODBTaskHistoryNew] 
      ([Id] 
      ,[Tag] 
      ,[Type] 
      ,[SourceFilePath] 
      ,[DestinationFilePath] 
      ,[Priority] 
      ,[State] 
      ,[SubState] 
      ,[StateDescription] 
      ,[Progress] 
      ,[Date_Created] 
      ,[Date_Queued] 
      ,[Date_Started] 
      ,[Date_Finished] 
      ,[Date_LastUpdated] 
      ,[Optional_ParentDependancyTaskId] 
      ,[Optional_isParentSuccessRequired] 
      ,[Transfer_ProgressBytes] 
      ,[Transfer_SpeedCurrentBps] 
      ,[Transfer_SpeedIntervals] 
      ,[IODrone_Id] 
      ,[IODrone_Version] 
      ,[Action] 
      ,[Date_TransferStarted] 
      ,[Optional_NotificationEmails] 
      ,[MaxRetryCount] 
      ,[CurrentRetryCount] 
      ,[Impersonation_Username] 
      ,[Impersonation_Password] 
      ,[AllowRewrite] 
      ,[SubTag] 
      ,[SourceLengthBytes] 
      ,[IODrone_Thread] 
      ,[Date_FileSizeFetched] 
      ,[Date_StornextTapeRetrievalStarted] 
      ,[Date_StornextTapeRetrievalFinished] 
      ,[IOServiceAddress] 
      ,[LogString] 
      ,[NotesString] 
      ,[TX_Date] 
      ,[SlowDownUpload]) 
    SELECT [Id] 
     ,[Tag] 
     ,[Type] 
     ,[SourceFilePath] 
     ,[DestinationFilePath] 
     ,[Priority] 
     ,[State] 
     ,[SubState] 
     ,[StateDescription] 
     ,[Progress] 
     ,[Date_Created] 
     ,[Date_Queued] 
     ,[Date_Started] 
     ,[Date_Finished] 
     ,[Date_LastUpdated] 
     ,[Optional_ParentDependancyTaskId] 
     ,[Optional_isParentSuccessRequired] 
     ,[Transfer_ProgressBytes] 
     ,[Transfer_SpeedCurrentBps] 
     ,[Transfer_SpeedIntervals] 
     ,[IODrone_Id] 
     ,[IODrone_Version] 
     ,[Action] 
     ,[Date_TransferStarted] 
     ,[Optional_NotificationEmails] 
     ,[MaxRetryCount] 
     ,[CurrentRetryCount] 
     ,[Impersonation_Username] 
     ,[Impersonation_Password] 
     ,[AllowRewrite] 
     ,[SubTag] 
     ,[SourceLengthBytes] 
     ,[IODrone_Thread] 
     ,[Date_FileSizeFetched] 
     ,[Date_StornextTapeRetrievalStarted] 
     ,[Date_StornextTapeRetrievalFinished] 
     ,[IOServiceAddress] 
     ,[LogString] 
     ,[NotesString] 
     ,[TX_Date] 
     ,[SlowDownUpload] 
    FROM [dbo].[IODBTaskHistory] 

План выполнения

enter image description here

Если это не ясно форма картина 99% от плана тратится на кластерный индекс вставки на новой идентификационной колонке

+1

как вы копируете данные? используя 'INSERT IN SELECT'? – ughai

+0

Да, это правильно – MrBliz

+1

Я считаю, что 'INSERT INTO SELECT' должен быть быстрее, если вы не заказываете' SELECT', и нет автоматического роста. существует ли какой-либо запрос DML в фоновом режиме для этой таблицы? можете ли вы подтвердить, что нет блокировки – ughai

ответ

0

По моему опыту самый быстрый путь к Отбросьте существующий кластерный индекс

drop index index_name on tablename; 

затем заново кластерный индекс:

create clustered index indexname on tablename(columnname1, columnanme2); 

Если вы собираетесь копировать данные затем скопировать в целевую таблицу, которая не содержит каких-либо индексов.После того, как все вставки выполнены, сначала создайте кластерный индекс, а затем все остальные индексы. Если вы создадите индексы перед вставками, у вас, скорее всего, будут много и много, разделов страниц, которые могут занять много времени.

+0

Разделение страниц не будет проблемой кластеризованного индекса, поскольку оно находится в столбце идентификации, что также означает, что создание кластерного индекса * после * вставки данных не имеет смысла, может также создать кластеризованный индекс первым и нужно только дважды записывать данные. – GarethD

Смежные вопросы