Лучший способ развернуть новый индекс в очень большой таблице в SQL Server 2008 - PullRequest
17 голосов
/ 22 февраля 2010

У меня есть производственная база данных с одной очень большой таблицей (много накопленных данных).

Для улучшения производительности запросов я использовал оптимизатор сервера sql, который предложил новый индекс.

Итак, я сделал копию рабочей базы данных для тестирования, и она действительно повышает производительность, однако моя проблема в том, что для создания индекса потребовалось около 24 часов, а во время создания индекса приложение не работает.

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

На данный момент у меня есть только несколько идей.

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

Конечно, у этого есть свой собственный набор проблем, таких как необходимость объединения данных вместе, поэтому мне не нравится эта идея по этой причине.

Это SQL Server 2008 Standard Ed.

Я обычно внедряю изменения базы данных по сценарию.

UPDATE: Другой идеей было бы перенести архивные данные из основной таблицы на несколько дней. Затем создайте индекс, когда таблица станет достаточно маленькой. Затем медленно перенесите данные обратно.

Ответы [ 4 ]

3 голосов
/ 22 февраля 2010

Учитывая недостаточную вычислительную мощность, доступную на машине ВМ, в сочетании с тем, что, несомненно, является довольно низкой пропускной способностью ввода-вывода, я бы на самом деле подумал о том, чтобы рассчитать время для резервного копирования, восстановления на полуадресном сервере, индексации и затем резервного копирования / восстановления обратно к машине VM.

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

3 голосов
/ 22 февраля 2010

Если вы используете Enterprise, вы можете использовать опцию ONLINE, равную CREATE INDEX, которая строит индекс без сохранения долгосрочных блокировок таблицы. Есть предостережения относительно его использования; обратитесь к связанной статье за ​​подробностями, и вы можете обнаружить, что влияние на производительность будет слишком большим. Но это академично, поскольку вы сказали, что используете стандарт (извините, что пропустили это сначала).

Тот факт, что это виртуальная машина, заставляет задуматься о том, чтобы временно «накачать» виртуальную машину или даже временно переместить ее на неработающую виртуальную машину. Для перестройки индекса для очень большой таблицы я бы подумал, что ОЗУ и скорость ввода-вывода будут самыми важными факторами; ВМ использует диск напрямую или виртуализированный диск? Можете ли вы временно переместить данные на физический диск? Такого рода вещи.

FWIW, ваша идея "взять и отключить и сделать это" - это именно то, что я сделал бы с базой данных MySQL (никогда не приходилось делать с базой данных SQL Server): отключить основную базу данных, получить снимок, очистите binlogs / enable binlogging и запустите его снова. Сделайте индекс на отдельной машине. Когда все будет готово, снимите БД, сделайте резервную копию обновленной БД (на всякий случай), отложите моментальный снимок, примените binlogs и восстановите БД. Это действительно так просто; Я ожидаю, что вы можете сделать это и с SQL Server. Конечно, предполагается, что вы можете применить 24 часа binlogs к (недавно оптимизированной) таблице в пределах приемлемого временного окна!

1 голос
/ 30 мая 2013

Почему вы не разделяете таблицу и не индексируете каждый раздел. Таким образом, вы индексируете только небольшие части, а затем можете объединить разделы позже.

1 голос
/ 22 февраля 2010

Другой подход может заключаться в том, чтобы не реализовывать индексы для всех таблиц, предлагаемых оптимизатором SQL Server, а в первую очередь реализовать это для одной таблицы или группы таблиц. Как вы упомянули, время простоя на несколько часов в порядке, поэтому, используя эти несколько часов, планируйте различные таблицы, по которым необходимо выполнить индексацию. Теперь ежедневно выбирайте те таблицы, индексы которых можно построить за указанное время простоя. Умная работа может легко решить эту проблему.

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

Надеюсь, это поможет ...

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