Переиндексация большого стола - как я облажался? - PullRequest
5 голосов
/ 27 марта 2009

У меня есть таблица размером 1 ТБ, 600 м, в которой неверно выбран индексированные столбцы, в частности кластеризованный индекс для столбца первичного ключа, который никогда не используется в запросе выбора.

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

Таблица в настоящее время выглядит так:

  • colA (PK, nvarchar (3)) [кластерный индекс pt b]

  • colB (PK, bigint) [кластерный индекс pt a]

  • colC (DateTime) [некластеризованный индекс]

  • colD (Деньги) [некластеризованный индекс]

  • colE (бит) [без индекса]

  • colF (бит) [без индекса]

  • colG (int) [без индекса]

  • больше неиндексированных столбцов

Я бы хотел изменить его так:

  • colA (PK, nvarchar (3)) [кластерный индекс pt a]

  • colB (PK, bigint) [некластеризованный индекс]

  • colC (DateTime) [некластеризованный индекс]

  • colD (Деньги) [кластерный индекс pt d]

  • colE (бит) [кластерный индекс pt b]

  • colF (бит) [кластерный индекс pt c]

  • colG (int) [кластерный индекс pt e]

  • больше неиндексированных столбцов

Два вопроса: 1) Как долго вы предполагаете, что это изменение займет (спецификация сервера в конце сообщения). К сожалению, это живая БД, и у меня не может быть простоев, если я не представляю, как долго она будет работать.

2) Ужасно ли добавлять столько столбцов в кластерный индекс? Обновления почти никогда не выполняются. Существует много вставок и много селекторов, которые всегда используют все предложенные индексированные строки в качестве параметров выбора.

Спецификация сервера: 5 дисков x 15kRPM в RAID 5, MS-SQL Sever 2005 и некоторые биты для их работы.

Ответы [ 8 ]

9 голосов
/ 27 марта 2009

Во-первых, я бы ИЗБЕЖАЛ, чтобы кластерный индекс был шире, чем он должен быть. Делать это на пять частей кажется непродуктивным. ВСЕ ли столбцы в этом составном кластерном индексе стабильны, например, никогда не меняется??

Если нет, я бы избегал их любой ценой. Кластерный индекс должен быть:

  • уникальный
  • стабильный
  • как можно более узкий

Вы можете изменить свои некластеризованные индексы - нет проблем. Но не делайте кластерный индекс грязным! Это определенно снизит вашу производительность!

Ознакомьтесь с отличными статьями Кимберли Триппа в блоге по индексированию:

Марк

6 голосов
/ 05 апреля 2009

Я внес изменения, и это не заняло много времени. Вот время для каждой операции: первый раз при запуске на сервере резервного копирования с одним диском 7200 об / мин, а второй на главном сервере с дисками 15k в RAID.

ALTER TABLE Table DROP CONSTRAINT [PK_Table]

2: 39 часов / 19 минут

CREATE CLUSTERED INDEX [IX_Clustered] ON [Table] 
(
 [a] ASC,
 [b] ASC,
 [c] ASC,
 [d] ASC,
 [e] ASC,
 [f] 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]

15: 30 часов / 2 часа

ALTER TABLE Table ADD CONSTRAINT
PK_hands PRIMARY KEY NONCLUSTERED 
(
 e,
 h
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

4 часа / 1 час

Наиболее часто используемый запрос на выборку теперь занимает <10 секунд, тогда как раньше это занимало от 10 до 15 минут. Хорошее улучшение! Время вставки выглядит немного быстрее. </p>

3 голосов
/ 27 марта 2009

У вас должна быть среда разработки с похожими характеристиками, которую вы можете использовать, чтобы попробовать это с копией действующей базы данных.

2 голосов
/ 27 марта 2009

Несмотря на то, что изменение кластеризованного индекса звучит так, как будто это здесь поможет, почему бы вам не попробовать сначала добавить (некластеризованный) покрывающий индекс?

Не следует разбирать таблицу при создании нового индекса и давать вам представление о том, какое улучшение производительности (если оно есть) приведет к этой реорганизации.

0 голосов
/ 27 марта 2009

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

0 голосов
/ 27 марта 2009

1) Сколько времени вы предположите, что это изменение займет (спецификация сервера в конце сообщения). К сожалению, это живая БД, и у меня не может быть простоев, если я не представляю, как долго она будет работать.

Это действительно, действительно зависит от данных. Только параметры таблицы не предоставляют достаточно информации. Может быть от нескольких минут (маловероятно) до нескольких дней (маловероятно), причем наиболее вероятное время находится где-то между ними.

2) Ужасно ли добавлять столько столбцов в кластерный индекс? Обновления почти никогда не выполняются. Существует много вставок и много селекторов, которые всегда используют все предложенные индексированные строки в качестве параметров выбора.

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

-Adam

0 голосов
/ 27 марта 2009

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

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

0 голосов
/ 27 марта 2009

Возможно, вам не нужно беспокоиться о времени простоя, поскольку возможно сделать изменение в реальном времени (без любого простоя). Относится к выпуску SQL Server 2005 Enterprise.

...