2009-04-01 2 views
6

У меня есть таблица с кластеризованным индексом в двух столбцах - первичный ключ для таблицы. Она определяются следующим образом:Лучший способ изменения кластеризованного индекса (PK) в SQL 2005

ALTER TABLE Table ADD CONSTRAINT [PK_Table] PRIMARY KEY CLUSTERED 
(
    [ColA] ASC, 
    [ColB] ASC 
)WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY] 

Я хочу, чтобы удалить этот кластерный индекс PK и добавить кластерный индекс, как следует и добавить ограничение первичного ключа, используя некластеризованный индекс, также показанный ниже.

CREATE CLUSTERED INDEX [IX_Clustered] ON [Table] 
(
    [ColC] ASC, 
    [ColA] ASC, 
    [ColD] ASC, 
    [ColE] ASC, 
    [ColF] ASC, 
    [ColG] ASC 
)WITH (PAD_INDEX = ON, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF,  DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, FILLFACTOR = 90, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = OFF) ON [PRIMARY] 

ALTER TABLE Table ADD CONSTRAINT 
    PK_Table PRIMARY KEY NONCLUSTERED 
    (
    ColA, 
    ColB 
) WITH(STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 

я собирался просто перенесите PK кластерного индекс, а затем добавить новый кластерный индекс, а затем добавить некластеризованный индекс первичного ключа, но я узнал, что сбросив существующий кластерный индекс может вызвать данные таблицы в быть переупорядоченным (см. ответ здесь What happens when I drop a clustered primary key in SQL 2005), который я не думаю, что это необходимо. Стол сбивает 1 ТБ, поэтому я действительно хочу избежать ненужного переупорядочения.

Вопрос: какой лучший способ перейти от существующей структуры к требуемой структуре?

EDIT: Просто хочу уточнить. Таблица 1TB, и у меня, к сожалению, нет места для создания временной таблицы. Если есть способ сделать это, не создавая таблицу temp, то, пожалуйста, дайте мне знать.

ответ

8

Если ваша таблица до 1 ТБ по размеру, и, вероятно, у него есть несколько строк в строках, я бы настоятельно рекомендовал НЕ сделать кластеризованный индекс намного толще!

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

Во-вторых, большой сложный кластерный индекс, который вы пытаетесь создать, значительно увеличит размер всех ваших некластеризованных индексов (поскольку они содержат все кластерное значение индекса на каждом листовом узле для поиска по закладкам).

Вопрос в том, почему вы пытаетесь это сделать ?? Не могли бы вы просто добавить еще один некластеризованный индекс с этими столбцами, чтобы потенциально покрывать ваши запросы? Почему это должен быть кластеризованный индекс? Я не вижу в этом никакого преимущества ....

Для получения дополнительной информации об индексации и особенно обсуждениях с кластерным индексом см. Kimberly Tripp's blog о индексах SQL Server - очень полезно!

Марк

4
  1. Создать новую таблицу:

    CREATE TABLE newtable (colA INT, colB INT) 
    
    • Вставить все значения из старой таблицы в новую таблицу:

      ВСТАВИТЬ INTO Новая_таблица SELECT * ИЗ таблицы

    • Оставьте старый т Уметь:

      DROP TABLE таблица

    • Переименуйте новую таблицу в старой таблице

      EXEC sp_rename 'Новая_таблица', 'стол'

    • Построение индексов:

      ALTER TABLE Таблица ADD CONSTRAINT PK_Table ПЕРВИЧНАЯ КЛЮЧА НЕРАСПРОСТРАНЕННАЯ ( ColA, ColB ) С (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

+0

Это не вариант. У меня есть таблица 1 ТБ на 1,5 Тбайт RAID. –

+0

SQL Server потребуется пространство как для переупорядочения, так и для перемещения. Если вы находитесь вне места, вы можете использовать опцию MOVE TO в DROP INDEX, чтобы создать таблицу на временном хранилище, а затем снова создать ее на своем RAID-массиве. – Quassnoi

+0

Вы можете перенести строки в куски, удалив их из источника, когда идете. Тем не менее, это будет очень медленный процесс. –

11

Это не полный ответ на ваш вопрос, но убедитесь, что если у вас есть другие индексы на столе, которые вы отбрасываете первым. В противном случае SQL Server придется перестроить их все, когда вы удалите кластерный индекс, а затем перестройте их снова, когда вы добавите новый кластерный индекс.Обычные шаги:

  1. Удалить все некластеризованные индексы
  2. Удалить кластерный индекс
  3. Добавить новый кластерный индекс
  4. Добавить обратно все некластеризованные индексы
+0

Ну, это был мой первоначальный план, но второй шаг удаления кластерного индекса заставляет все данные перемещаться. Я надеялся как-то объединить шаги 2 и 3, чтобы избежать ненужного перемещения данных. –

-1

Кластерные индексы фактически не изменяют физический порядок данных, хранящийся в таблице это сам. Так было не с SQL 6.5.

Данные на страницах хранятся в правильном порядке. Страницы могут быть сохранены на диске в любом физическом порядке.

+0

это правда? У меня создалось впечатление, что физический порядок данных определялся ключом кластеризации. –

+0

Данные на страницах хранятся в правильном порядке. Страницы могут быть сохранены на диске в любом физическом порядке. – mrdenny

+2

Возможно, вы захотите обновить свой ответ, включив это различие. –

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