Дефрагментация индексов MS SQL для платформы 8.3.22

15.11.23

База данных - Инструменты администратора БД

Начиная с 8.3.22 фирма "1С" убрала блокировки БД на уровне страниц; если БД расположена в MS SQL, то стала возникать проблема при дефрагментации индексов с использованием команды ALTER INDEX REORGANIZE. Предлагаю модификацию известного скрипта, который позволяет обойти эту проблему.

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Скрипт для дефрагментация индексов для нескольких баз MS SQL
.sql 3,24Kb
28
28 Скачать (1 SM) Купить за 1 850 руб.

Начиная с 8.3.22 фирма "1С" убрала блокировки БД на уровне страниц, если БД расположена в MS SQL, то в индексах параметр Allow page locks стал равен False.

Проблема в том, что при дефрагментации индексов с использованием команды ALTER INDEX REORGANIZE возникает ошибка "The index ... on table ....... cannot be reorganized because page level locking is disabled.".

Предлагаю модификацию скрипта с сайта Microsoft, который позволяет обойти эту проблему.

-- Ensure a USE <databasename> statement has been executed first.
SET NOCOUNT ON;

DECLARE @objectid INT;
DECLARE @indexid INT;
DECLARE @partitioncount BIGINT;
DECLARE @schemaname NVARCHAR(130);
DECLARE @objectname NVARCHAR(130);
DECLARE @indexname NVARCHAR(130);
DECLARE @allowpagelocks INT;
DECLARE @partitionnum BIGINT;
DECLARE @partitions BIGINT;
DECLARE @frag FLOAT;
DECLARE @command NVARCHAR(4000);

-- Conditionally select tables and indexes from the sys.dm_db_index_physical_stats function
-- and convert object and index IDs to names.
SELECT object_id AS objectid,
    index_id AS indexid,
    partition_number AS partitionnum,
    avg_fragmentation_in_percent AS frag
INTO #work_to_do
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'LIMITED')
WHERE avg_fragmentation_in_percent > 10.0
    AND index_id > 0;

-- Declare the cursor for the list of partitions to be processed.
DECLARE partitions CURSOR
FOR
SELECT *
FROM #work_to_do;

-- Open the cursor.
OPEN partitions;

-- Loop through the partitions.
WHILE (1 = 1)
BEGIN;

    FETCH NEXT
    FROM partitions
    INTO @objectid,
        @indexid,
        @partitionnum,
        @frag;

    IF @@FETCH_STATUS < 0
        BREAK;

    SELECT @objectname = QUOTENAME(o.name),
        @schemaname = QUOTENAME(s.name)
    FROM sys.objects AS o
    INNER JOIN sys.schemas AS s
        ON s.schema_id = o.schema_id
    WHERE o.object_id = @objectid;

    SELECT @indexname = QUOTENAME(name), @allowpagelocks = allow_page_locks
    FROM sys.indexes
    WHERE object_id = @objectid
        AND index_id = @indexid;

    SELECT @partitioncount = count(*)
    FROM sys.partitions
    WHERE object_id = @objectid
        AND index_id = @indexid;

    -- 30 is an arbitrary decision point at which to switch between reorganizing and rebuilding.
    IF @frag < 30.0
		SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REORGANIZE';

    IF @frag >= 30.0
        SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REBUILD';

    IF @partitioncount > 1
        SET @command = @command + N' PARTITION=' + CAST(@partitionnum AS NVARCHAR(10));

	IF @frag < 30.0 AND @allowpagelocks = 0
		SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' SET (ALLOW_PAGE_LOCKS = ON);' 
		    + @command + N'; ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' SET (ALLOW_PAGE_LOCKS = OFF)';

    EXEC (@command);

    PRINT N'Executed: ' + @command;
END;

-- Close and deallocate the cursor.
CLOSE partitions;

DEALLOCATE partitions;

-- Drop the temporary table.
DROP TABLE #work_to_do;
GO

К публикации приложен скрипт для дефрагментации индексов для нескольких баз.

дефрагментация 8.3.22

См. также

Инструментарий разработчика Чистка данных Свертка базы Инструменты администратора БД Системный администратор Программист Руководитель проекта Платформа 1С v8.3 Россия Платные (руб)

Инструмент представляет собой обработку для проведения свёртки или обрезки баз данных. Работает на ЛЮБЫХ конфигурациях (УТ, БП, ERP и т.д.). Поддерживаются серверные и файловые базы, управляемые и обычные формы. Может выполнять свертку сразу нескольких баз данных и выполнять их автоматически без непосредственного участия пользователя. Решение в Реестре отечественного ПО

8400 руб.

20.08.2024    13584    105    46    

106

Инструменты администратора БД Инструментарий разработчика Роли и права Программист Платформа 1С v8.3 Конфигурации 1cv8 Россия Платные (руб)

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

15000 руб.

10.11.2023    11710    43    27    

66

Инструменты администратора БД Роли и права Системный администратор Программист Пользователь 8.3.14 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:Документооборот 1С:Зарплата и кадры государственного учреждения 3 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Платные (руб)

Роли… Вы тратите много времени и сил на подбор ролей среди около 2400 в ERP или 1500 в Рознице 2, пытаясь понять какими правами они обладают? Вы все время смотрите права в конфигураторе или отчетах чтоб создать нормальные профили доступа? Вы хотите наглядно видеть какие права дает профиль и редактировать все в простом виде? А может хотите просто указать подсистему и дать права на просмотр и добавление на объекты и не лезть в дебри прав и чтоб обработка сама подобрала нужные роли? Все это теперь стало возможно! Обновление от 18.09.2024, версия 1.2

18000 руб.

06.12.2023    10418    47    5    

78

Инструментарий разработчика Инструменты администратора БД Системный администратор Программист Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Россия Платные (руб)

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

4800 руб.

14.01.2013    190943    1152    0    

919

Закрытие периода Инструменты администратора БД Корректировка данных Бухгалтер Пользователь Бухгалтерский учет 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Платные (руб)

Расширение «Оперативное проведение» в 4 раза уменьшает время проведения документов и закрытия месяца. Является комплексным решением проблем 62 и 60 счетов. Оптимизирует проведение при включенной функциональной опции «Раздельный учет НДС». Используется в более 10 организациях уже 2 года. Совместимо с конфигурацией Бухгалтерия 3.0 (+КОРП).

14400 руб.

29.04.2020    33741    108    152    

75

Инструменты администратора БД Системный администратор Программист Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

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

3600 руб.

06.02.2017    32572    145    18    

51

Архивирование (backup) Инструменты администратора БД Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:Управление торговлей 11 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Платные (руб)

Данная разработка позволит решить вопрос с резервным копированием Ваших баз в автоматическом режиме, расположенных на сервере 1С. Система умеет ставить блокировки на вход, блокировать фоновые задания, принудительно отключать сеансы пользователей. И все это система делает в автоматически при создании бэкапа (или через команду). Выгрузка происходит в родной формат 1С - .dt. Так же система умеет архивировать данные выгрузки с установкой пароля. Умеет менять расширение файла zip или dt на любое указанное вами, что позволит сохранить выгрузки от шифровальщика. Может удалять старые копии выгрузок, оставляя указанное количество резервных копий, начиная с самой поздней. Только для WINDOWS!

6000 руб.

06.11.2012    73669    629    45    

88

Инструменты администратора БД Пользователь Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Платные (руб)

Многие сталкиваются с проблемой когда изображения, находящиеся в базе разные по объему и размерам. Менеджеры могут добавить файлы в очень высоком разрешении, объемом свыше 20 Мегабайт. База данных становится слишком большой, выгрузка на сайт идёт медленно и требуется много место на хостинге. Как сжать картинки и уменьшить размер базы 1С? Это можно сделать с помощью данной обработки. Существует возможность выбрать различные варианты для того чтобы уменьшить картинки: в разы, в процентах от первоначального объема, а также сделать картинки одинаковой ширины. В результате размер базы 1С значительно сократится (в зависимости от количества и размера картинок), а изображения станут небольшого объема, равными по ширине, почти без потери качества. Работает на управляемых формах для УТ 11, КА, ERP.

3000 руб.

21.07.2022    10139    9    4    

17
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
3. baturo 38 15.11.23 12:48 Сейчас в теме
(1) Так и делается, но не для всех индексов, а только для тех, где снять флаг Allow page lock:

IF @frag < 30.0 AND @allowpagelocks = 0
		SET @command = N'ALT ER   INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' SET (ALLOW_PAGE_LOCKS = ON);' 
		    + @command + N'; ALT ER   INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' SET (ALLOW_PAGE_LOCKS = OFF)';
2. SerVer1C 862 15.11.23 11:14 Сейчас в теме
EXEC sp_msforeachtable 'ALT ER INDEX ALL ON ? SET (ALLOW_PAGE_LOCKS = ON, ALLOW_ROW_LOCKS = ON)'
EXEC sp_msforeachtable 'ALT ER INDEX ALL ON ? REORGANIZE WITH (LOB_COMPACTION = ON)'
EXEC sp_msforeachtable 'ALT ER INDEX ALL ON ? SET (ALLOW_PAGE_LOCKS = OFF, ALLOW_ROW_LOCKS = ON)'
GO

* <ALTER> пишется слитно

3 строчки вместо портянки
(не благодарите)
user926893; rrustam11983; medexe; +3 Ответить
4. paulwist 20.11.23 14:59 Сейчас в теме
(2)
3 строчки вместо портянки


Ммм, как минимум 4-е строчки :)

USE MyDB
5. Alias 176 24.11.23 12:05 Сейчас в теме
разбирали ещё полтора месяца назад:
https://partners.v8.1c.ru/forum/topic/2152862

Там же привели все варианты, которые тут описывают, и ещё вот такой:

sp_msforeachtable N'
ALT ER   INDEX ALL ON ? SET (ALLOW_PAGE_LOCKS = ON)
DBCC INDEXDEFRAG (<имя базы данных>, ''?'')
ALT ER   INDEX ALL ON ? SET (ALLOW_PAGE_LOCKS = OFF)
'


P.S. Почему на Инфостарте слово ALTER вставляется в сообщение с пробелом? Я так не писал. И не исправляется, зараза. Конечно, там просто ALT ER INDEX ALL ....
6. baturo 38 27.11.23 05:57 Сейчас в теме
(5)
ели все вар

(5)


P.S. Почему на Инфостарте слово ALTER вставляется в сообщение с пробелом? Я так не писал. И не исправляется, зараза. Конечно, там просто ALT ER INDEX ALL ...


Не все индексы требуют реорганизации, зачем тратить ресурс сервера - сначала установить флаг ALLOW_PAGE_LOCKS для всех индексов, а затем его сбрасывать.

В данной версии скрипта флаг устанавливается и сбрасывается только тогда, когда требуется реорганизация индекса;
это более оптимально.
7. user866660 22.07.24 14:46 Сейчас в теме
(5)
Почему на Инфостарте слово ALTER вставляется в сообщение с пробелом?


От SQL Injection защищаются, наверное :)
8. Xershi 1559 02.12.24 19:23 Сейчас в теме
Адаптировал данный скрипт под версию из публикации Регламентные операции с индексами
-------------------------------------------
-- НАСТРАИВАЕМЫЕ ПАРАМЕТРЫ
-- База данных для анализа
--USE WorkBase
-- Убедитесь, что сначала был выполнен оператор USE <имя_базы_данных>.

-------------------------------------------
-- СЛУЖЕБНЫЕ ПЕРЕМЕННЫЕ 
DECLARE @object_id INT; -- ID объекта
DECLARE @index_id INT; -- ID индекса
DECLARE @partition_count BIGINT; -- количество секций, если индекс секционирован
DECLARE @schemaname NVARCHAR(130); -- имя схемы, в которой находится таблица
DECLARE @objectname NVARCHAR(130); -- имя таблицы
DECLARE @indexname NVARCHAR(130); -- имя индекса
DECLARE @allowpagelocks INT; -- разрешить блокировку страницы
DECLARE @partitionnum BIGINT; -- номер секции
--DECLARE @partitions BIGINT; -- не используется
DECLARE @fragmentation_in_percent FLOAT; -- процент фрагментации индекса
DECLARE @command NVARCHAR(4000); -- инструкция T-SQL для дефрагментации либо реиндексации

-------------------------------------------
-- ТЕЛО СКРИПТА

-- Отключаем вывод количества возвращаемых строк, это несколько ускорит обработку
SET NOCOUNT ON;

-- Удалим временные таблицы, если вдруг они есть.
IF OBJECT_ID('tempdb.dbo.#work_to_do') IS NOT NULL DR OP   TABLE #work_to_do

-- Отбор таблиц и индексов с помощью системного представления sys.dm_db_index_physical_stats
-- и конвертируем идентификаторы объектов и индексов в имена.
-- Отбор только тех объектов которые:
--  являются индексами (index_id > 0)
--  фрагментация которых более 5%
--  количество страниц в индексе более 128
SEL ECT
    object_id AS object_id,
    index_id AS index_id,
    partition_number AS partitionnum,
    avg_fragmentation_in_percent AS fragmentation_in_percent
INTO #work_to_do
FR OM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'LIMITED')
WHERE index_id > 0 
    AND avg_fragmentation_in_percent > 5.0
    AND page_count > 128;

-- Объявляем курсор для списка секций, которые необходимо обработать.
DECLARE partitions CURSOR
FOR
SEL ECT *
FR OM #work_to_do;

-- Открываем курсор.
OPEN partitions;

-- Цикл по секциям.
WHILE (1 = 1)
BEGIN;

    FETCH NEXT
    FR OM partitions
    INTO @object_id,
        @index_id,
        @partitionnum,
        @fragmentation_in_percent;

    IF @@FETCH_STATUS < 0
        BREAK;

    -- Собираем имена объектов по ID
    SEL ECT @objectname = QUOTENAME(o.name),
        @schemaname = QUOTENAME(s.name)
    FR OM sys.objects AS o
    INNER JOIN sys.schemas AS s
        ON s.schema_id = o.schema_id
    WH ERE o.object_id = @object_id;

    SELECT @indexname = QUOTENAME(name),
        @allowpagelocks = allow_page_locks
    FR OM sys.indexes
    WH ERE object_id = @object_id
        AND index_id = @index_id;

    SELECT @partition_count = count(*)
    FR OM sys.partitions
    WH ERE object_id = @object_id
        AND index_id = @index_id;

    -- Если фрагментация менее или равна 30%, тогда дефрагментация, иначе реиндексация.
    IF @fragmentation_in_percent < 30.0
        SET @command = N'ALT ER   INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REORGANIZE';

    IF @fragmentation_in_percent >= 30.0
        SET @command = N'ALT ER   INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REBUILD';

    IF @partition_count > 1
        SET @command = @command + N' PARTITION=' + CAST(@partitionnum AS NVARCHAR(10));

    IF @fragmentation_in_percent < 30.0 AND @allowpagelocks = 0
        SET @command = N'ALT ER   INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' SET (ALLOW_PAGE_LOCKS = ON);'
            + @command + N'; ALT ER   INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' SET (ALLOW_PAGE_LOCKS = OFF)';

    -- Выполняем команду
    EXEC (@command);

    PRINT N'Index: object_id=' + STR(@object_id) + ', index_id=' + STR(@index_id) + ', fragmentation_in_percent=' + STR(@fragmentation_in_percent);
    PRINT N'Executed: ' + @command;
END;

-- Закрытие курсора
CLOSE partitions;

DEALLOCATE partitions;

-- Удаление временной таблицы
DR OP   TABLE #work_to_do;
GO
Показать

Как я понимаю оператор USE нужно выполнить, чтобы гарантировать выполнение на нужной базе. Но если делать через Агент SQL Server - Задания, то это можно не делать, т.к. там явно указывается для какой базы выполняется скрипт. А переменную partitions нигде не используется, поэтому эти операторы закомментировал.
Кстати у кого есть сервер 1С до 8.3.22 данный скрипт будет работать?
9. Xershi 1559 12.12.24 15:49 Сейчас в теме
(8) если будете копировать сприпт, проверьте все конструкции. В текст вставлены лишние пробелы. Наверное защита форума.
В частности синтаксис около:
DR OP 
 TABLE
SEL ECT
FR OM
WHERE
ALT ER 
 INDEX

Дробит слова и вставляет от 1 до 2 лишних пробелов. Поэтому просто скопировать не получится.
10. 1Pawel 1 14.01.25 15:11 Сейчас в теме
Понравился скрипт от Tavalik, доработанный Филипповым Сергеем (здесь).
Есть опция обновления статистики после реорганизации.
Поддержка параллелизма, сортировки в tempdb, реиндексация онлайн некоторых типов индексов.
Процент фрагментации для реорганизации и реиндексации выведен в блок переменных.
Более подробный вывод лога.

Я адаптировал этот скрипт под MSSQL 2012, где не поддерживаются параметры UPDATE STATISTICS до MSSQL 2014. Убрал неподдерживаемые параметры Rebuild online в редакциях Standard. Обновление статистики при реорганизации включено всегда.
Прикрепленные файлы:
ReindexRebuild_1Pawel.sql
ReindexRebuild_Filippov.sql
ReindexRebuild_AnyBases_Filippov.sql
Оставьте свое сообщение