Как сделать реиндексацию базы в sql server

Обновлено: 07.07.2024

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

Если в работающей системе наблюдаются какие-либо симптомы проблем с производительностью, следует проверить, что в системе правильно настроены и регулярно выполняются все рекомендуемые регламентные операции на уровне СУБД.

Выполнение регламентных процедур должно быть автоматизировано. Для автоматизации этих операций рекомендуется использовать встроенное средства MS SQL Server: Maintenance Plan. Существуют так же другие способы автоматизации выполнения этих процедур. В настоящей статье для каждой регламентной процедуры дан пример ее настройки при помощи Maintenance Plan для MS SQL Server 2016.

Для MS SQL Server рекомендуется выполнять следующие регламентные операции:

  • Обновление статистик
  • Очистка процедурного КЭШа
  • Дефрагментация индексов
  • Реиндексация таблиц базы данных

Рекомендуется регулярно контролировать своевременность и правильность выполнения данных регламентных процедур.

Обновление статистик

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

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

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

Чтобы быть максимально полезной для оптимизатора запросов, статистика должна быть точной и свежей. Время от времени SQL Server периодически сам обновляет статистику — данное поведение регулируется опциями AUTO_CREATE_STATISTICS и AUTO_UPDATE_STATISTICS.
Кроме того, при пересоздании индексов, статистика по ним обновляется автоматически с включенным флагом FULLSCAN, гарантирующим наиболее точное распределение данных. При реорганизации индексов же — статистика не обновляется.

Когда данные в таблицах изменяются очень часто, целесообразно выполнять избирательное обновление статистики вручную, с помощью операции UPDATE STATISTICS.

Запустите MS SQL Server Management Studio и подключитесь к серверу СУБД. Откройте папку Management и создайте новый план обслуживания:

Оптимизация 1С

Оптимизация 1С.jpg

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

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

Обновление статистик необходимо проводить с включенной опцией Full Scan.

003.jpg

Сохраните созданный план. При наступлении указанного в расписании срока обновление статистик будет запущено автоматически.

Очистка процедурного КЭШа

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

Возможна ситуация, при которой MS SQL Server, ориентируясь на устаревшую статистическую информацию, построит неоптимальный план запроса. Этот план будет сохранен в процедурном КЭШе и использован при повторном вызове такого же запроса. Если Вы обновили статистику, но не очистили процедурный кэш, то SQL Server может выбрать старый (неоптимальный) план запроса из КЭШа вместо того, чтобы построить новый (более оптимальный) план.

Таким образом, рекомендуется всегда после обновления статистик очищать содержимое процедурного КЭШа.

Оптимизация 1С

Ускорение работы 1с

Дефрагментация индексов

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

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

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

Оптимизация.jpg

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

Настройте задачу, указав базу данных (или несколько баз данных) и выбрав необходимые таблицы. Если точно неизвестно, какие таблицы следует указать, то устанавливайте значение All.

007.jpg

Реиндексация таблиц базы данных

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

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

008.jpg

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

Настройте задачу, указав базу данных (или несколько баз данных) и выбрав необходимые таблицы. Если точно неизвестно, какие таблицы следует указать, то устанавливайте значение All.

REINDEX — перестроить индексы

Синтаксис

Описание

REINDEX перестраивает индекс, обрабатывая данные таблицы, к которой относится индекс, и в результате заменяет старую копию индекса. Команда REINDEX применяется в следующих ситуациях:

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

Параметр хранения индекса (например, фактор заполнения) был изменён, и теперь требуется, чтобы это изменение вступило в силу в полной мере.

Параметры

Перестраивает указанный индекс. TABLE

Перестраивает все индексы в текущей базе данных. При этом обрабатываются также индексы в общих системных каталогах. Эту форму REINDEX нельзя выполнить в блоке транзакции. SYSTEM

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

Имя определённого индекса, таблицы или базы данных, подлежащих переиндексации. В настоящее время REINDEX DATABASE и REINDEX SYSTEM могут переиндексировать только текущую базу данных, так что их параметр должен соответствовать имени текущей базы данных. CONCURRENTLY

С этим указанием PostgreSQL перестроит индекс, не устанавливая никаких блокировок, которые бы предотвращали добавление, изменение или удаление записей в таблице, тогда как по умолчанию операция перестроения индекса блокирует запись (но не чтение) в таблице до своего завершения. При переиндексации в неблокирующем режиме есть ряд особенностей, о которых следует знать, — см. Rebuilding Indexes Concurrently ниже.

Для временных таблиц REINDEX всегда выполняется более простым, неблокирующим способом, так как они не могут использоваться никакими другими сеансами. VERBOSE

Выводит отчёт о прогрессе после переиндексации каждого индекса.

Замечания

В случае подозрений в повреждении индекса таблицы пользователя, этот индекс или все индексы таблицы можно перестроить, используя команду REINDEX INDEX или REINDEX TABLE .

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

Один из вариантов сделать это — выключить сервер PostgreSQL и запустить его снова в однопользовательском режиме, с параметром -P в командной строке. Затем можно выполнить REINDEX DATABASE , REINDEX SYSTEM , REINDEX TABLE или REINDEX INDEX , в зависимости от того, что вы хотите восстановить. В случае сомнений выполните REINDEX SYSTEM , чтобы перестроить все системные индексы в базе данных. Затем завершите однопользовательский сеанс сервера и перезапустите сервер в обычном режиме. Чтобы подробнее узнать, как работать с сервером в однопользовательском интерфейсе, обратитесь к справочной странице postgres .

Можно так же запустить обычный экземпляр сервера, но добавить в параметры командной строки -P . В разных клиентах это может делаться по-разному, но во всех клиентах на базе libpq можно установить для переменной окружения PGOPTIONS значение -P до запуска клиента. Учтите, что хотя этот метод не препятствует работе других клиентов, всё же имеет смысл не позволять им подключаться к повреждённой базе данных до завершения восстановления.

Действие REINDEX подобно удалению и пересозданию индекса в том смысле, что содержимое индекса пересоздаётся с нуля, но блокировки при этом устанавливаются другие. REINDEX блокирует запись, но не чтение родительской таблицы индекса. Эта команда также устанавливает блокировку ACCESS EXCLUSIVE для обрабатываемого индекса, что блокирует чтение таблицы, при котором задействуется этот индекс. DROP INDEX , напротив, моментально устанавливает блокировку ACCESS EXCLUSIVE на родительскую таблицу, блокируя и запись, и чтение. Последующая команда CREATE INDEX блокирует запись, но не чтение; так как индекс отсутствует, обращений к нему ни при каком чтении не будет, что означает, что блокироваться чтение не будет, но выполняться оно будет как дорогостоящее последовательное сканирование.

Для перестраивания одного индекса или индексов таблицы необходимо быть владельцем этого индекса или таблицы. Для переиндексирования схемы или базы данных необходимо быть владельцем этой схемы или базы. Заметьте в частности, что вследствие этого не только суперпользователи могут перестраивать индексы таблиц, принадлежащих другим пользователям. Однако из этих правил есть исключение — когда команду REINDEX DATABASE , REINDEX SCHEMA или REINDEX SYSTEM выполняет не суперпользователь, индексы общих каталогов будут пропускаться, если только данный каталог не принадлежит этому пользователю (как правило, это так). Разумеется, суперпользователи могут переиндексировать всё без ограничений.

Переиндексирование секционированных таблиц или секционированных индексов не поддерживается. Переиндексировать можно каждую секцию по отдельности.

Неблокирующее перестроение индексов

Перестроение индекса может мешать обычной работе с базой данных. Обычно PostgreSQL блокирует запись в переиндексируемую таблицу и выполняет всю операцию построения индекса за одно сканирование таблицы. Другие транзакции могут продолжать читать таблицу, но при попытке вставить, изменить или удалить строки в таблице они будут заблокированы до завершения перестроения индекса. Это может оказать нежелательное влияние на работу производственной базы данных. Индексация очень больших таблиц может занимать много часов, и даже для маленьких таблиц перестроение индекса может заблокировать записывающие процессы на время, неприемлемое для производственной системы.

PostgreSQL поддерживает перестроение индексов в режиме минимизации блокировок записи. Этот режим включается указанием CONCURRENTLY команды REINDEX . С данным указанием PostgreSQL должен выполнить два сканирования таблицы для каждого индекса, который нужно перестроить, и должен дождаться завершения всех активных транзакций, которые могут использовать данный индекс. В связи с этим в неблокирующем режиме производится в целом больше действий, и длительность переиндексирования значительно увеличивается. Однако благодаря тому, что во время перестроения индекса могут выполняться другие обычные операции, этот режим полезен, когда требуется перестроить индексы в производственной среде. Разумеется, другие операции могут несколько замедлиться из-за дополнительной нагрузки на процессор, память и ввод/вывод, связанной с перестроением индекса.

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

В каталог pg_index добавляется переходное определение индекса, которое затем заменит старое. Для предотвращения каких-либо изменений в схеме во время операции обрабатываемые индексы, а также связанные с ними таблицы защищаются блокировкой SHARE UPDATE EXCLUSIVE на уровне сеанса.

Затем выполняется второй проход, на котором в индекс вносятся кортежи, добавленные в таблицу во время первого прохода. Это действие также выполняется в отдельной транзакции для каждого индекса.

Если имя индекса с пометкой INVALID оканчивается на ccnew , это переходный индекс созданный при параллельной операции, и для исправления ситуации рекомендуется удалить его, выполнив DROP INDEX , а затем попытаться ещё раз выполнить REINDEX CONCURRENTLY . Если же имя нерабочего индекса оканчивается на ccold , значит, это исходный индекс, удалить который по какой-то причине не получилось. Такой индекс рекомендуется просто удалить, так как нужный индекс был перестроен успешно.

Обычное построение индекса допускает одновременное построение других индексов для таблицы обычным методом, но неблокирующее построение для конкретной таблицы в один момент времени допускается только одно. Однако в любом случае никакие другие изменения схемы таблицы в это время не разрешаются. Другое отличие состоит в том, что в блоке транзакции может быть выполнена обычная команда REINDEX TABLE или REINDEX INDEX , но не REINDEX CONCURRENTLY .

Как и любая длительная транзакция, операция REINDEX с таблицей может повлиять на возможность удаления кортежей параллельной операцией VACUUM с какой-либо другой таблицей.

Команда REINDEX SYSTEM не поддерживает указание CONCURRENTLY , так как системные каталоги нельзя переиндексировать в неблокирующем режиме.

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

Примеры

Перестроение одного индекса:

Перестроение всех индексов таблицы my_table :

Перестроение всех индексов в определённой базе данных, в предположении, что целостность системных индексов под сомнением:

Перестроение индексов таблицы, допускающее одновременные операции чтения и записи с затрагиваемыми в процессе переиндексации отношениями:

У меня есть резервная копия Database1 от недели назад. Резервное копирование выполняется в планировщике еженедельно, и я получаю .bak файл. Теперь я хочу поиграть с некоторыми данными, поэтому мне нужно восстановить их в другой базе данных - Database2 .

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

Есть ли какой-нибудь другой способ восстановить его Database2 или, по крайней мере, как просмотреть данные этого файла .bak?

ps: второй ответ по приведенной выше ссылке выглядел многообещающе, но завершается с ошибкой:

Восстановление списка файлов прекращается ненормально

Для создания базы данных MyTempCopy с содержанием your.bak .

Пример (восстанавливает резервную копию базы данных с именем creditline в MyTempCopy;

Привет, я, кажется, что-то упустил, он продолжает выдавать ошибку backkup set holds a backup of a database other than existing "tmp" database , которая, я понимаю. Должна ли to фраза быть реальным физическим путем MyTempCopy ?

Следует использовать REPLACE, RECOVERY, чтобы решить это. Так что это будет: RESTORE DATABASE MyTempCopy FROM DISK='e:\mssql\backup\creditline.bak' WITH REPLACE, RECOVERY, MOVE 'CreditLine' TO 'e:\mssql\MyTempCopy.mdf', MOVE 'CreditLine_log' TO 'e:\mssql\MyTempCopy_log.ldf'

SQL Server 2008 R2:

Для существующей базы данных, которую вы хотите «восстановить: из резервной копии другой базы данных, выполните следующие действия:

Sql 2014 .. Шаг 6a: Измените базу данных назначения на базу данных, в которую вы хотите восстановить. Шаг 9 и 10: Об этом следует позаботиться, изменив базу данных Destination. Но дважды проверьте это, зайдя в Файлы и проверив имена файлов, как описано в первоначальном шаге 9 и 10.

Обратите внимание, что шаги 4 и 7 важно настроить, чтобы не перезаписывать существующую базу данных.

где base_1c - имя базы данных.
Если хранимой процедуры _1sp_DBReindex нет в базе данных (база не 1С), то можно выполнить такой код (это и есть код хранимой процедуры _1sp_DBReindex):

USE base_1c
DECLARE @TableName char(32)
DECLARE SysCur CURSOR FOR SELECT name FROM sysobjects WHERE type='U'
OPEN SysCur
FETCH NEXT FROM SysCur INTO @TableName
WHILE @@FETCH_STATUS=0 BEGIN
DBCC DBREINDEX(@TableName)
FETCH NEXT FROM SysCur INTO @TableName
END
CLOSE SysCur
DEALLOCATE SysCur

if exists (select * from sysobjects where and sysstat & 0xf = 4)
drop procedure dbo._1sp_DBReindex
CREATE PROCEDURE _1sp_DBReindex AS
SET NOCOUNT ON
DECLARE @TableName char(32)
DECLARE SysCur CURSOR FOR SELECT name FROM sysobjects WHERE type='U'
OPEN SysCur
FETCH NEXT FROM SysCur INTO @TableName
WHILE @@FETCH_STATUS=0 BEGIN
DBCC DBREINDEX(@TableName)
FETCH NEXT FROM SysCur INTO @TableName
END
CLOSE SysCur
DEALLOCATE SysCur

Как проверить (восстановить) базу на MS SQL Server средствами сервера

Проверку логической целостности нужно выполнять штатными средствами 1С:Предприятия (Тестирование и исправление ИБ). В случае, если такую проверку не удается выполнить, следует проверить физическую целостность БД средствами MS SQL. Для проверки целостности средствами MS SQL нужно выполнить следующую команду:

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

После выполнения DBCC CHECKDB нужно не забыть вернуться в нормальный режим (выйти из режима "single user"):

Читайте также: