Лучший способ изменить кластерный индекс (PK) в SQL 2005 - PullRequest
6 голосов
/ 01 апреля 2009

У меня есть таблица с кластерным индексом по двум столбцам - первичный ключ для таблицы. Он определяется следующим образом:

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, затем добавить новый кластеризованный индекс и затем добавить некластеризованный индекс первичного ключа, но я узнал, что удаление существующего кластеризованного индекса приведет к переупорядочению данных таблицы (см. ответ здесь Что происходит, когда я отбрасываю кластеризованный первичный ключ в SQL 2005 ), что я не считаю необходимым. Стол сбивает 1 ТБ, поэтому я очень хочу избежать ненужного переупорядочения.

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

РЕДАКТИРОВАТЬ: Просто хочу уточнить. Таблица составляет 1 ТБ, и у меня, к сожалению, нет места для создания временной таблицы. Если есть способ сделать это без создания временной таблицы, пожалуйста, дайте мне знать.

Ответы [ 4 ]

11 голосов
/ 01 апреля 2009

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

  1. Удалить все некластеризованные индексы
  2. Удалить кластерный индекс
  3. Добавить новый кластерный индекс
  4. Добавить обратно все некластеризованные индексы
8 голосов
/ 02 апреля 2009

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

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

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

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

Дополнительную информацию об индексировании и, в частности, о дискуссиях по кластерным индексам см. В блоге Кимберли Триппа об индексах SQL Server - очень полезно!

Марк

4 голосов
/ 01 апреля 2009
  1. Создать новую таблицу:

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

      ВСТАВИТЬ INTO newtable ВЫБРАТЬ * С таблицы

    • Бросить старый стол:

      Стол DROP TABLE

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

      EXEC sp_rename 'newtable', 'table'

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

      Стол ALTER TABLE ДОБАВИТЬ ОГРАНИЧЕНИЕ PK_Table ПЕРВИЧНЫЙ КЛЮЧ НЕКЛЮЧЕННЫЙ ( COLA, ColB ) С (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [ОСНОВНОЙ]

0 голосов
/ 06 апреля 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...