Зачем в 1С нужно периодически пересчитывать итоги по регистрам?
База данных - Инструменты администратора БД
Попробуем разобраться...
Что такое итоги по регистрам?
Это агрегированные значения из таблицы движений регистров, которые используются для быстрого вычисления остатка или оборота по каким-либо измерениям. Хранятся они в отдельных таблицах.
Какие итоги бывают?
По умолчанию для регистров существуют итоги по месяцам и актуальные итоги (только для регистров остатков).
Почему "по умолчанию"? Потому что администратор базы может управлять наличием итогов с помощью методов "УстановитьИспользованиеИтогов" и "УстановитьИспользованиеТекущихИтогов".
Что происходит, когда документ записывает движения по регистру?
Представим, что проводим документ "Реализация товаров и услуг" в типовой УТ 10.3 с 1 строкой в табличной части задним числом за 01.01.2013, а дата расчета итогов - 28.02.2013. Во время проведения происходит запись регистра накопления "Товары на складах".
При этом в СУБД:
1) добавляется новая запись в таблицу движений регистра накопления
2) в таблице итогов происходит обновление актуальных итогов - из остатка на 01.11.3999 отнимается списанное количество.
3) если дата документа меньше крайней даты расчета итогов, то происходит обновление итогов по месяцам (причем столько раз, насколько месяцев дата документа меньше даты расчета итогов) - т.е. будут обновлены итоги на 01.02.2013 и 01.03.2013.
Итого в результате записи документа произошла модификация 4-х строк только по этому регистру.
И где проблема?
А проблема в том, что с течением времени в таблице итогов накапливаются записи с нулевыми значениями. Представим, что в предыдущем примере реализация полностью списала весь остаток товара на тот момент. Получается, что 2 итога по месяцам и актуальные итоги будут обнулены - сначала поступление добавило положительное значение в итоги, а реализация его обнулила. В виртуальных таблицах значение пропадет, но нулевые записи в физических таблицах остаются.
Посмотрим на таблицу итогов этого регистра в СУБД - получим по периодам общее число записей и число записей, для которых все ресурсы равны 0:
Получается, что мы имеем некое количество "мусорных" записей в итогах по месяцам и почти 30% "мусорных" записей в актуальных итогах.
А ведь актуальные итоги - это наиболее часто используемые данные для оперативно проводимых документов. И лишние строки в этом массиве данных приводят к замедлению выполнения запросов, т.е. документы проводятся дольше, больше риск возникновения блокировок.
Как исправить ситуацию?
Следует отметить, что делать это нужно регулярно. Частота проведения определяется в индивидуальном порядке в зависимости от интенсивности работы с базой.
Есть несколько вариантов.
Самый простой и очевидный - в конфигураторе запустить полный пересчет итогов. Минусы - если база большая, то этот процесс займет длительное время.
Другой вариант - запуск пересчет итогов средствами встроенного языка.
Например, для пересчета актуальных итогов (как наиболее важных с точки зрения оперативной работы пользователей) можно использовать следующий код:
Для каждого Рег из Метаданные.РегистрыНакопления Цикл
Если Рег.ВидРегистра = Метаданные.СвойстваОбъектов.ВидРегистраНакопления.Остатки Тогда
РегистрыНакопления[Рег.Имя].ПересчитатьТекущиеИтоги();
КонецЕсли;
КонецЦикла;
Для каждого Рег из Метаданные.РегистрыБухгалтерии Цикл
РегистрыБухгалтерии[Рег.Имя].ПересчитатьТекущиеИтоги();
КонецЦикла;
Если ваша база работает уже не один год и ее объем достаточно большой, то этот код выполниться на порядок быстрее полного пересчета итогов. Поэтому можно даже сделать этот код регламентным заданием и выполнять каждую ночь или на выходных.
Выполним эту процедуру и посмотрим в СУБД на ту же таблицу:
Видно, что в актуальных итогах (первая строка) нулевых записей больше нет.
Похожим образом выполняется пересчет итогов по месяцам.
Необходимо использовать метод "УстановитьПериодРассчитанныхИтогов()" - пересчитать можно, например, только несколько последних месяцев и не нагружать систему лишним пересчетом прошлых лет.
В совсем запущенных случаях пересчет итогов только средствами 1С занимает очень много времени.
Фактически платформе 1С сначала надо очистить огромный объем записей в таблицах итогов, а потом заново их наполнить обновленными данными меньшего размера.
При этом платформа удаляет итоги помесячно с помощью DELETE. Соответственно, это требует много ресурсов и времени.
Сильно ускорить процесс можно путем предварительной очистки итогов в СУБД с помощью TRUNCATE TABLE.
Как один из вариантов:
1) отключаем всех пользователей и делаем бэкап базы средствами MSSQL;
2) генерируем запросы на очистку всех таблиц итогов по регистрам накопления:
В контексте базы данных выполняем запрос:
SELECT 'TRUNCATE TABLE ' + name FROM sys.tables
WHERE name like '_AccumRgT%'
Результат вывода копируем, вставляем в окно запроса и выполняем в контексте базы данных.
3) Запускаем пересчет итогов через Тестирование и исправление в Конфигураторе.
При таком подходе процесс займет существенно меньше времени, т.к. СУБД не будет тратить время на тяжелую операцию удаления старых записей.
Что еще следует помнить?
Пересчет итогов влияет на статистику - она становится не актуальной. Соответственно, после пересчета итогов вы можете получить не улучшение, а, наоборот, ухудшение производительности. Поэтому нужно не забывать запускать полное обновление статистики в СУБД и очистку процедурного кэша после проведения пересчета.
Пересчет итогов также приводит к практически 100% фрагментации индексов по таблицам итогов.
Для больших баз данных это может существенно сказываться на производительности.

Варианта решения этой проблемы два:
1) (долгий, но простой) - После пересчета итогов запускать реиндексацию таблиц из конфигуратора через "Тестирование и исправление".
Не запускайте одновременно пересчет итогов и реиндексацию, т.к. конфигуратор сначала перестроит индексы, а затем пересчитает итоги, т.е. таблицы итогов все равно будут фрагментированы. Необходимо выполнять эти операции раздельно.
2) (более быстрый, только для клиент-серверного варианта) - Воспользоваться одним из множества скриптов в интернете для перестроения только наиболее фрагментированных индексов.
UPD. Посмотрите также очень содержательный комментарий Алексея Лустина в этой теме (сообщение №58).
ТОП-6 инструментов для разработчика 1С
Подборка лучших инструментов для разработчика 1С включает Toolkit, DCT, OneDebugger, PrintWizard, DataFormWizard и Infostart MCP. Любой инструмент со скидкой 20% при покупке от двух решений.
Вступайте в нашу телеграмм-группу Инфостарт
Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».
- 0% комиссии — оплата напрямую исполнителю;
- Исполнители любого масштаба — от отдельных специалистов до команд под проект;
- Прямой обмен контактами между заказчиком и исполнителем;
- Безопасная сделка — при необходимости;
- Рейтинги, кейсы и прозрачная система откликов.
См. также
Инструментарий разработчика Чистка данных Свертка базы Инструменты администратора БД Системный администратор Разработчик Руководитель проекта 1С:Предприятие 8 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 Россия Платные (руб)
Инструмент представляет собой обработку для проведения свёртки или обрезки баз данных. Работает на ЛЮБЫХ конфигурациях (УТ, БП, ERP, УНФ, КА и т.д.). Поддерживаются серверные и файловые базы, управляемые и обычные формы, интерфейс 8.5. Может выполнять свертку одновременно в несколько потоков, а также без непосредственного участия пользователя. Решение в Реестре отечественного ПО.
24900 руб.
20.08.2024 83261 432 171
Инструменты администратора БД Роли и права Системный администратор Разработчик Пользователь 1С 8.3 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, пытаясь понять какими правами они обладают? Вы все время смотрите права в конфигураторе или отчетах чтоб создать нормальные профили доступа? Вы хотите наглядно видеть какие права дает профиль и редактировать все в простом виде? А может хотите просто указать подсистему и дать права на просмотр и добавление на объекты и не лезть в дебри прав и чтоб обработка сама подобрала нужные роли? Все это теперь стало возможно! Обновление от 17.04.2026, версия 1.4.1, работает в 1С:ФРЕШ!
23180 руб.
06.12.2023 25071 85 14
Инструменты администратора БД Инструментарий разработчика Роли и права Разработчик 1С:Предприятие 8 1C:Бухгалтерия Россия Платные (руб)
Расширение позволяет без изменения кода конфигурации выполнять проверки при вводе данных, скрывать от пользователя недоступные ему данные, выполнять код в обработчиках. Не изменяет данные конфигурации, легко устанавливается практически на любую конфигурацию на управляемых формах.
17000 руб.
10.11.2023 28743 103 46
Поиск данных Инструменты администратора БД Корректировка данных Разработчик Бухгалтер Пользователь 1С:Предприятие 8 1С:Управление торговлей 10 1С:Управление производственным предприятием 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x 1С:Управление нашей фирмой 3.0 Россия Платные (руб)
Решение для автоматической сверки данных между любыми конфигурациями 1С. Помогает контролировать и проверять обмены, проверять наличие документов при переносах данных, находить изменения в закрытых периодах
9760 руб.
14.11.2025 6171 28 8
Информационная безопасность Инструменты администратора БД Инструментарий разработчика Учет документов Системный администратор Разработчик Аналитик Бухгалтер Пользователь Руководитель проекта 1С 8.3 1С 8.5 Розничная и сетевая торговля (FMCG) Платные (руб)
Контроль ввода данных в 1С: проверка заполнения реквизитов, обязательные поля, контроль перед записью и проведением, запрет проведения документа. Позволяет настраивать любые проверки данных в 1С 8.3/8.5 от обязательных полей до сложных условий – без открытия конфигуратора и написания кода. Готовое расширение, которое подключается и работает сразу.
6000 руб.
15.04.2026 4169 12 0
Инструментарий разработчика Инструменты администратора БД Системный администратор Разработчик Аналитик 1С:Предприятие 8 1С 8.3 1С 8.5 1C:ERP 1С:УТ 1С:ДО 1С:Бухгалтерия 3.0 1С:ERP. Управление холдингом 1С:Зарплата и Управление Персоналом 3.x 1С:Управление нашей фирмой 3.0 1С:Управление торговлей 11 Россия Платные (руб)
Универсальный инструмент программиста для администрирования конфигураций. Сборник наиболее часто используемых обработок под единым интерфейсом.
5000 руб.
14.01.2013 217336 1252 0
Закрытие периода Инструменты администратора БД Корректировка данных Бухгалтер Пользователь 1С:Предприятие 8 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Платные (руб)
Расширение «Оперативное проведение» в 4 раза уменьшает время проведения документов и закрытия месяца. Является комплексным решением проблем 62 и 60 счетов. Оптимизирует проведение при включенной функциональной опции «Раздельный учет НДС». Используется в более 10 организациях уже 2 года. Совместимо с конфигурацией Бухгалтерия 3.0 (+КОРП).
14640 руб.
29.04.2020 52955 145 164
Файловый обмен (TXT, XML, DBF), FTP Поиск данных Инструменты администратора БД Корректировка данных Системный администратор Разработчик 1С:Предприятие 8 1C:Бухгалтерия 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Платные (руб)
Данная обработка позволит Вам легко и просто, а главное - быстро, выполнить сравнение данных между ЛЮБЫМИ базами (и РИБ, по правилам конвертаций) по контрольным суммам выбранных объектов баз 1С, работающих на платформах 8.3 и выше. Удобный и понятный интерфейс в виде "мастера". Высокая скорость сравнения достигается за счет специального алгоритма расчета контрольной суммы объекта/записи и сравнения по данным суммам объектов 2х баз через файл. Имеется возможность выбора реквизитов, по которым система будет сравнивать объекты. Сравнение количества записей в движениях документов, возможность сравнивать данные по правилам конвертации и не только! Выбор объектов конфигурации для КАЖДОГО узла в отдельности с индивидуальным отбором для каждого объекта конфигурации, работа с FTP, сохранение или загрузка настроек, сохранение или загрузка результата сравнения, регистрация на обмен объекта и его движений. (Обновление от 12.11.2024, версия 2.2-2.5)
24400 руб.
27.10.2017 47845 33 15
Тут самое главное понять что запись с нулевым количеством в итоге, совершенно не означает что эта запись не нужна.
При проектировании реляционных СУБД считается (считалось) что операции CRUD (Create, Read, Update, Delete) по затратам ресурсов распределяются следующим образом
1. Легкие: Read, Update
2. Средние: Create
3. Тяжелая: Delete
И исходя из логики поведения объекта Регистр, который меняется часто; и из-за больших затрат на удаление записей, существует позиция что:
запись итога не имеет смысла удалять синхронно в момент возникновения нулевого итога, потому что "ноль" не означает "NULL" и потому что велика вероятность того что следующая транзакция "захочет" увеличить или уменьшить итог и он станет ненулевым и нам необходимо будет понести затраты еще и на операцию вставки.
отсюда и посыл, что записи с нулевым итогом имеет смысл удалять асинхронно, то есть в определенный момент времени - но опять же неизвестно как определить этот самый "определенный момент". Такое определение должно лежать на ответственных за приложение - чаще всего как мы знаем пересчет итогов возникает в один момент времени при закрытии периодов учета и подается как некая подготовительная процедура. Вот тут и кроется проблема о которой давно известно - бизнес-задача Закрытие периода не является задачей обеспечения технической стабильности и бизнес иногда может на неё "забить".
У меня в практике была таблица с 400 миллионами записей с нулевым итогом.
И вот тут я могу сказать что разработчики платформы слегка "недочлись" (от слова "недочет") - дело в том что согласно вышеописанному архитектурному решению явно становится понятно, что:
Удалять записи с нулевым итогом нужно по тем ключам (комплектам измерений), по которым длительное время не было операций UPDATE. А этого функционала в платформе нет - есть только глобальный пересчет. В крупных конторах это решается SQL Job'ом выполняющем примерно следующую работу:
1. найти 1 комплект ключей (измерений) по которому не было движений за последний месяц и которые на данный момент нулевые
2. по данному комплекту измерений удалить запись из таблицы итогов
обычно данный Job запускается раз в 10 секунд, выбирается TOP 1 чтобы уменьшить время блокировки на затратную операцию удаления. Естественно в такие базы уже встроены и планы обслуживания по пересчету статистики и перестроению дефрагментированных индексов. В случаях когда таких "ненужных" записей очень много - то обычно уменьшают период запуска Job, либо отказываются от Регистра Итогов - потому что если у вас много ключей уходит в "ноль" и больше не используется, скорее всего у вас по данным ключам 2 операции движения "пришел" и "ушел" - зачем хранить такую информацию в регистре итогов совершенно не ясно.
Ну и про статистику тут тоже все изъезжено - масcовые операции CREATE И DELETE, а также UPDATE ключевого столбца ведут к нарушению дерева поиска по индексу (диапазона распределений ключа по страницам данных) - ну то есть в поисковом диапазоне 1..10 вполне себе может оказаться ключ со значением 23 - так SQL было удобней, потому страница данных была рядом со страницей ключа 7, а ключ 6 заместо которого встал ключ 23 окажется в диапазоне 100..134 - что тоже было удобней исходя из страниц данных. Пример на пальцах - но думаю суть отражает.
Вообще про статистику в момент массовых операций удобно понять следующее: когда вы делается массовую вставку данных SQL пытается вам помочь и оперирует близостью страниц данных для оптимизации вставки и совершенно забывает про оптимизацию операций чтения, где параметром является статистика (диапазоны поиска ключа в таблице - распределение ключа), поэтому чтобы после массовых вставок операции чтения были тоже быстрыми - необходимо восстановить работоспособность инструмента оптимизации чтения выполнив UPDATE STATS.
---
Да и еще забыл сказать - массовое удаление ведет к массовому возникновению фантомных записей: запись числится удаленной но место занимает - такая ситуация ведет к снижению производительности операций выборок типа SCAN (просмотр).
подумал что очередной пересказ "желтых методичек"
но был приятно удивлен
глубоким знанием автором архитектуры базы данных 1С.
наверное стоит отметить в публикации,
что картинки с результатами запросов
сделаны в SQL Server Management Studio
для клиент-серверной базы данных.
--
Возможно кому-то будет интересно,
запросы к итогам из статьи можно также сделать
в обработке ""
так же в консоли можно выполнить код на языке 1С для пересчета итогов.
можно также упомянуть про регламентное задание в типовых конфигурациях
выполняющих пересчет итогов.
В УПП-1.2 например крутится регламентное задание "ПересчетИтоговРегистровНакопления",
выполняющее следующий код:
Процедура ПересчетИтоговРегистров() Экспорт
НаДату = НачалоМесяца(ТекущаяДата())-1;
ПересчетРегистров(РегистрыНакопления, НаДату, Метаданные.СвойстваОбъектов.ВидРегистраНакопления.Остатки);
ПересчетРегистров(РегистрыБухгалтерии, НаДату);
КонецПроцедуры
Процедура ПересчетРегистров(МенеджерРегистров, НаДату, ОграничениеПоВидуРегистра = Неопределено)
Для Каждого МенеджерРегистра ИЗ МенеджерРегистров Цикл
МетаданныеРегистра = Метаданные.НайтиПоТипу(ТипЗнч(МенеджерРегистра));
Если ОграничениеПоВидуРегистра <> Неопределено И МетаданныеРегистра.ВидРегистра <> ОграничениеПоВидуРегистра Тогда
Продолжить;
КонецЕсли;
ПересчитатьРегистрПоДате(МенеджерРегистра, НаДату);
КонецЦикла;
КонецПроцедуры
Процедура ПересчитатьРегистрПоДате(МенеджерРегистра, НаДату)
Если МенеджерРегистра.ПолучитьПериодРассчитанныхИтогов()<НаДату Тогда
МенеджерРегистра.УстановитьПериодРассчитанныхИтогов(НаДату);
Иначе
МенеджерРегистра.ПересчитатьИтоги();
КонецЕсли;
КонецПроцедуры
ПоказатьИ ещё, лучше всё-таки писать так: "Если рег.ВидРегистра=Метаданные.СвойстваОбъектов.ВидРегистраНакопления.Остатки Тогда...", а не через СокрЛП
Все время хотелось написать "Если рег.ВидРегистра=ВидРегистраНакопления.Остатки ..", а, оказывается, надо было через Метаданные.
Спасибо!
Возник вопрос, а почему в процедуре пересчета текущих итогов используются строки
РегистрНакопления.УстановитьИспользованиеТекущихИтогов(Ложь);
РегистрНакопления.УстановитьИспользованиеТекущихИтогов(Истина);вместо
РегистрНакопления.ПересчитатьТекущиеИтоги();?
И еще вопрос: есть количественные оценки в росте производительности в связи с избавлением от "нулевых" строк?
Но я обходился и простым удалением нулевых записей через sql.
По поводу прироста - если такая операция давно не делалась, то прирост ощутим (количественно не скажу). Если её делать каждый месяц... То явного прироста не будет.
sanches,
вот есть много вякой вкуснятины для 1С-77
правда требуется
--
в том числе обработка "", которая:
позволяет переустанавливать ТА,
расчитывая итоги регистров прямыми запросами 1с++
Позволяет также:
- пересчитать итоги по указанным регистрам (остатков и оборотов);
- все действия можно проводить в разделенном режиме (устанавливается блокировка);
- каждый месяц открывать за вас новый период, не выгоняя срочно всех из базы;
там запросы писать надо по другому и
желательно прирулить какие-нибудь примочки, чтобы
прямые запросы в dbf в монопольном режиме работали.
:)
...
но клиент просил
Спасибо, а что-нибудь для 77 и 2000 SQL можете посоветовать? Наверняка там такая же ситуация.
а не кто и не говорит что эти примочки к 1С
для монопольного режима какая-то новость
(разве что субъективно :) ).
--
просто их надо будет прикручивать,
если захочется что бы прямые запросы в dbf
работали в монопольном режиме.
Спасибо за ссылки)))
(34) yuraos,
Чтобы таблицы итогов не опухли бы, для этого есть в бухучете инструмент: Закрытие месяца, закрытие года
А без этого было бы вообще жесть..
за статью ставлю однозначно "+", так как меня давно интересовал такой вопрос, для чего закрывать месяц, год, что будет... Теперь ясно что к чему)))
Если при расчетах задним числом. модифицируются промежуточные и актуальные итоги. и вдруг получается в итогах ноль. Итог - это по сути куча. Куча - всегда итог правильный, например нулевой. Почему тупо скулем не удалить нулевые итоги...?????
Правильно ли я понимаю, что в регистре остатков нулевых значений в принципе не должно быть, а 0 это ошибка в логике пересчета регистров?
p.s. Я сам про это думал и как-то даже на тестовой удалял (SQL запросом), но на рабочую перенести так и не решился, хотя никаких отклонений в работе системы выявлено не было.
Тут самое главное понять что запись с нулевым количеством в итоге, совершенно не означает что эта запись не нужна.
При проектировании реляционных СУБД считается (считалось) что операции CRUD (Create, Read, Update, Delete) по затратам ресурсов распределяются следующим образом
1. Легкие: Read, Update
2. Средние: Create
3. Тяжелая: Delete
И исходя из логики поведения объекта Регистр, который меняется часто; и из-за больших затрат на удаление записей, существует позиция что:
запись итога не имеет смысла удалять синхронно в момент возникновения нулевого итога, потому что "ноль" не означает "NULL" и потому что велика вероятность того что следующая транзакция "захочет" увеличить или уменьшить итог и он станет ненулевым и нам необходимо будет понести затраты еще и на операцию вставки.
отсюда и посыл, что записи с нулевым итогом имеет смысл удалять асинхронно, то есть в определенный момент времени - но опять же неизвестно как определить этот самый "определенный момент". Такое определение должно лежать на ответственных за приложение - чаще всего как мы знаем пересчет итогов возникает в один момент времени при закрытии периодов учета и подается как некая подготовительная процедура. Вот тут и кроется проблема о которой давно известно - бизнес-задача Закрытие периода не является задачей обеспечения технической стабильности и бизнес иногда может на неё "забить".
У меня в практике была таблица с 400 миллионами записей с нулевым итогом.
И вот тут я могу сказать что разработчики платформы слегка "недочлись" (от слова "недочет") - дело в том что согласно вышеописанному архитектурному решению явно становится понятно, что:
Удалять записи с нулевым итогом нужно по тем ключам (комплектам измерений), по которым длительное время не было операций UPDATE. А этого функционала в платформе нет - есть только глобальный пересчет. В крупных конторах это решается SQL Job'ом выполняющем примерно следующую работу:
1. найти 1 комплект ключей (измерений) по которому не было движений за последний месяц и которые на данный момент нулевые
2. по данному комплекту измерений удалить запись из таблицы итогов
обычно данный Job запускается раз в 10 секунд, выбирается TOP 1 чтобы уменьшить время блокировки на затратную операцию удаления. Естественно в такие базы уже встроены и планы обслуживания по пересчету статистики и перестроению дефрагментированных индексов. В случаях когда таких "ненужных" записей очень много - то обычно уменьшают период запуска Job, либо отказываются от Регистра Итогов - потому что если у вас много ключей уходит в "ноль" и больше не используется, скорее всего у вас по данным ключам 2 операции движения "пришел" и "ушел" - зачем хранить такую информацию в регистре итогов совершенно не ясно.
Ну и про статистику тут тоже все изъезжено - масcовые операции CREATE И DELETE, а также UPDATE ключевого столбца ведут к нарушению дерева поиска по индексу (диапазона распределений ключа по страницам данных) - ну то есть в поисковом диапазоне 1..10 вполне себе может оказаться ключ со значением 23 - так SQL было удобней, потому страница данных была рядом со страницей ключа 7, а ключ 6 заместо которого встал ключ 23 окажется в диапазоне 100..134 - что тоже было удобней исходя из страниц данных. Пример на пальцах - но думаю суть отражает.
Вообще про статистику в момент массовых операций удобно понять следующее: когда вы делается массовую вставку данных SQL пытается вам помочь и оперирует близостью страниц данных для оптимизации вставки и совершенно забывает про оптимизацию операций чтения, где параметром является статистика (диапазоны поиска ключа в таблице - распределение ключа), поэтому чтобы после массовых вставок операции чтения были тоже быстрыми - необходимо восстановить работоспособность инструмента оптимизации чтения выполнив UPDATE STATS.
---
Да и еще забыл сказать - массовое удаление ведет к массовому возникновению фантомных записей: запись числится удаленной но место занимает - такая ситуация ведет к снижению производительности операций выборок типа SCAN (просмотр).
Меня же зацепило "разработчикам платформы виднее" ;-).
1) Все-таки, решение проблемы с нулевыми записями на уровне платформы не такое тривиальное, есть разные варианты и везде есть плюсы и минусы. Вряд ли можно угодить всем. А переложить ответственность за чистку итогов на конечного пользователя системы - в принципе, хороший вариант.
2) Стараюсь быть осторожен в формулировках относительно работы фирмы 1С. Уже несколько раз попадал на цензуру и замечания с их стороны. А в немилость впасть не хочется :).
Итак - для PostgreSQL и статья и комментарий (58) также действуют в полном объеме.
Поэтому тем кто будет читать эту статью и комментарии напомню, что правильный подход к исправлению выглядит следующим образом (в не зависимости от сервера СУБД)
0. Если вы вдруг обнаружили что у вас много нулевых записях в таблице итогов
1. садитесь совместно группой - ключевой пользователь системы 1С, ведущий разработчик системы 1С, DBA системы (или тот кто считает себя таковым)
2. договариваетесь о том когда у бизнес-пользователя происходят фиксация бизнес-результатов по регистрам накопления - для УТ это обычно неделя, для БП - месяц и т.д. Это время называем "Время Ч"
3. ведущий разработчик реализует регламентную очистку "за день до сдачи финансовых результатов" - то есть "Время Ч минус 1 рабочий день" назовем это "время X"
3.1 крайне желательно фиксировать в журнал регистрации количество записей до очистки, и после очистки - то есть "было 1 миллион, стало 100 тысяч"
4. DBA запускает регламентные операции "по приведению в порядок базы после массового удаления" - запускает он это в технологическое окно после "Времени X"
4.1 крайне желательно фиксировать результаты приведения в порядок базы - по крайне мере в простых текстовые файлики.
через 6 регламентных запусков по очистке регистров - группа встречается и смотрит результаты по очистке.
5. регистры сокращающиеся при очистке на 80% и более - регистры на гарантированный рефакторинг:
5.1 потому как "регистры накопления" должны накапливать данные, они же не "регистры ежедневного обнуления" - скорее всего это регистры сведений
5.2 потому как такие регистры скорее всего означают незнания функционала типовых конфигураций - скорее всего функционал бизнес-пользователями связанных регистраторов таких регистров используются не по назначению
Еще раз напомню - что платформа 1С тут не причем: нулевые записи - в 90% случаев вопрос к бизнес-пользователям системы и прикладникам
1. Легкие: Read, Update
2. Средние: Create
3. Тяжелая: Delete
Операция Update никогда не считалась в реляционных СУБД легкой по затратам ресурсов как и Delete
Это самы тяжелые операции, где помимо поиска самой записи требуется обеспечить возможность отката/возврата измененного блока, а так же журнала повтора.
Проектировщики-диверсанты какие-то...
(58)
После пересчета итогов производительность упала - 5,1 с. на 1 реализацию.
После обновления статистики - 0,9 с. на 1 реализацию.
Примерно трехкратный прирост.
Но каждая ситуация индивидуальна.
P.S. дописанная УТ 10.2
Уважаемый автор, для меня "упала" = стала хуже, а Вы как бы намекаете, что это прекрасно.
- автор указал длительность в секундах
- чего вам сделал Алексей, что вы ему всякую хрень приписываете
Можно проверить, что будет если удалить все нулевые записи в регистрах в 8-ке:
сделать две тестовые базы, копии рабочей
- в одной удалить все нулевые записи SQL-скриптом
- в другой сделать пересчет регистров штатными средствами платформы
Потом запросом сравнивать по два регистра из этих двух баз что получается и где есть различия.
Если различий нет, то можно смело использовать в повседневной жизни, если есть станет ясно что делать дальше и какие записи не удалять...
Простыми расчетами выходит, что там периодов итогов 1812*12=21744 штук. Умножив это на число нулевых записей в каждом периоде можно сильно удивиться:-)
БД - SQL 11 Gb
Это бухгалтерия за один год.
Выявились проблемы при формировании отчета Обороты счета за год по 20 счету по 3 субконто + подразделения.
за 1 кв отчет Формируется в течении 20 секунд
за 2 квартала 8 минут
за три и четыре квартала отчет не формируется...
после пересчета итогов за четыре квартала формируется в течении 2 минут.
Это ответ на вопросы по реальному приросту после пересчета итогов.
В ЗиУП тоже самое... при чем за месяц формировался отчет по разному от 15 минут до 45 минут... сейчас в пределах 15 секунд.
Так что я думаю что там еще есть кое что с дефрагментацией БД.
Спасибо.
а в ЗУПе за счет чего такой выйгрыш?
Насколько я понял это больше актуально для регистров
И еще возник вопрос: пересчет итогов также актуален и для файлового варианта? (или это все важно для клиент-серверном варианте работы).
Спасибо.
Реиндексация через Конфигуратор - это физическое удаление всех индексов и новое их создание. Соответственно, устраняются все возможные проблемы (а платформа с индексами до сих пор иногда косячит).
Реиндексация в СУБД - это перестроение уже существующих индексов, но СУБД понятия не имеет что такое 1С и какие индексы должны быть в каких табличках. И, если они у вас неправильные по структуре (например, кто-нибудь залез ручками поправил), то они такими и останутся.
недели 3 назад - пытался перерасчитать итоги, после того как внес дополнительно в базу около 100 000 документов.
База тогда весила около 170Гб. Бэкап базы весил около 2.7Гб.
В итоге - перерасчитать итоги у меня не удалось, ибо на это ушло более суток и клиенты начали кричать, пришлось жестко кикнуть 1С. Я боялся худшего. Что случилось в итоге - размер быза вырос до 270Гб, однако бэкап - теперь весит 1.7 Гига. Я уже думал что капут. Но - отчеты строится начали быстрее, данные показывали верные, в любых итогах строил и т.д.
Теперь я на тестовом сервере поднимаю бэкап и база весит всего лишь 60Гб. Но все работает отлично и даже лучше.
Например отчет по регистру по всей номенклатуре (около 120 000) по партиям на складах (около 10 000 000 записей) строится всеголишь 10 - 15 секунд (я не считаю тут расчет ширины колонок, с нима намного дольше, но это отдельная история), за весь период, со всеми выбранными ресурсами.
Отсюда вопрос - нужны ли вообще эти итоги? Так как в нашем случае - они реально замедляли работу, ибо работаем мы с партиями, т.е. для нас не критично строить отчеты по месяцам, нам важно именно партия.
Если не нужны, то как их можно отключить? Ну так что бы навсегда :)
В 8.1 вроде еще выгружались, но точно не уверен.
Кстати по этой причине частенько выгрузка/загрузка БД даёт прирост производительности, особенно в базах которые не обслуживались.
Не увидел, как это повлияет на файловый вариант базы?
Наоборот. Чем интенсивнее проводятся документы - тем быстрее появляются "нулевые" строки, и тем чаще требуется производить пересчет итогов.
Правильно ли я понимаю, что в случае файлового режима работы этого делать не нужно, и пересчет итогов сразу должен дать положительный результат?
Алексей, огромное спасибо за статью, очень познавательно и кратко.
У меня появились пара вопросов "в тему" (в статье ответа не увидел):
1. В случае, если к примеру у меня рассчитаны итоги на конец января 31.01.2013, а я делаю запрос к остаткам на конец февраля 28.02.2013, а сегодня - 25.03.2013, и существует много движений за весь этот период, то каким образом система предоставит мне запрашиваемые данные: будет рассчитывать "на лету"?
2. Тот же пример что и в п.1. Но в данном случае я провожу "задним числом" приход от 10.01.2013, то как поведет себя система в этом случае: она будет пересчитает уже рассчитанный итог на конец января и актульный итог, верно? А если бы у меня были рассчитаны итоги еще и на конец февраля, то система бы пересчитывала еще и их? Если это так, то делаю вывод: рассчитанные итоги "мешают" при больших объемах изменений "задним числом" (например, при первом закрытии квартала после запуска системы с начала года, когда всё еще корректируются начальные остатки). То есть не всегда расчет итогов приведет к повышению производительности. Правильный ли вывод я сделал?
Спасибо.
2. Если меняем данные в прошлом, например 25.05.12, система меняет обороты в мае 2012 и остатки во всех последующих итогах. Поэтому не рекомендуется рассчитывать итоги на будущее, в идеале - на последний прошедший месяц.
результат на моей маленькой базе
Итог по размерам:
(может быть недоступна, т.к. не прошла еще модерацию)
.
Перепровел тестовую и контрольные базы, пордяка 3200 доков, все задним числом, какого-то мега ощутимого прироста не наблюдал - процентов5-8, что можно списать на погрешности... Правда львиная доля тяжелых доков, по которым существенно упаковались таблицы итогов - у меня при заднем числе не перепроводятся, поэтом м.б. и не показательно у меня.. тем более что база достаточно маленькая - чуть более 4 гига всего, ожидаемый эффект м.б. на ней и не проявится...?
Очень полезная статья. Пересчитала итоги всех регистров и заметила, что в некоторых регистрах нулевые записи частично остались.
Например, РегистрНакопления.ТоварыПолученныеИтог до пересчета нулевых записей в актуальных итогах 271, после пересчета 63, а в помесячных итогах нулевые записи совсем не ушли.
Подскажите, пожалуйста, в чем может быть проблема?
У регистра в конфигураторе стоит признак "Разрешить разделение итогов", в пользовательском режиме данное свойство не стоит, после пересчета итогов через запрос SQL видно что нулевые записи в регистре остались, при этом количество нулевых записей в 2 раза меньше, чем записей всего. Если раскрыть эти нулевые записи, то видно, что у них поле _Splitter = 1. Т.е. к каждой ненулевой записи, у которой _Splitter = 0 таблицы итога создалась нулевая запись, у которой _Splitter = 0.
P.S. По лицензионному соглашению 1С разработчики не имеют что-либо менять в скульных базах в обход платформы :)
Да, только скорей всего это вступает в противоречие с лицензией от Майкрософт и с гражданским кодексом РФ.
Статья 1334. Исключительное право изготовителя базы данных
1. Изготовителю базы данных, создание которой (включая обработку или представление соответствующих материалов) требует существенных финансовых, материальных, организационных или иных затрат, принадлежит исключительное право извлекать из базы данных материалы и осуществлять их последующее использование в любой форме и любым способом (исключительное право изготовителя базы данных). Изготовитель базы данных может распоряжаться указанным исключительным правом. При отсутствии доказательств иного базой данных, создание которой требует существенных затрат, признается база данных, содержащая не менее десяти тысяч самостоятельных информационных элементов (материалов), составляющих содержание базы данных (абзац второй пункта 2 статьи 1260).
Никто не вправе извлекать из базы данных материалы и осуществлять их последующее использование без разрешения правообладателя, кроме случаев, предусмотренных настоящим Кодексом. При этом под извлечением материалов понимается перенос всего содержания базы данных или существенной части составляющих ее материалов на другой информационный носитель с использованием любых технических средств и в любой форме.
2. Исключительное право изготовителя базы данных признается и действует независимо от наличия и действия авторских и иных исключительных прав изготовителя базы данных и других лиц на составляющие базу данных материалы, а также на базу данных в целом как составное произведение.
3. В течение срока действия исключительного права на базу данных правообладатель по своему желанию может зарегистрировать базу данных в федеральном органе исполнительной власти по интеллектуальной собственности. К такой регистрации применяются правила статьи 1262 настоящего Кодекса.
(п. 3 в ред. Федерального закона от 12.03.2014 N 35-ФЗ)
я думаю, это - фигня.
очень сомнительно, когда в лицензионном соглашении фигурируют ограничения, накладываемые на использование продуктов третьих фирм.
скуль - 1сине не принадлежит.
и что там кто и как в скуле будет делать - пофиг.
если в случае проблем 1с скажет типа "структура вашей базы в скуле не соответсвует типовому шаблону построения 1Сной базы" - тады да... но \то имхо совсем не относится к тому что я в скульной базе что-то в обход платофрмы сделаю. можем мне какой-нить тривиальный update на 100 миллионов записей быстрей скулем сделать чем через всяких передастов.
Кроме того, на базу у 1С не может быть никаких прав в принципе - даже потенциальных. Поэтоу она принципиально и не может быть объектом ЛС. Могут быть какие-то иные документы, нормы, правила эксплуатации, отказы от гарантий при нарушении - но точно не ЛС, как раз ЛС тут не в тему.
Этот пункт легко оспорить, просто никому не надо (ибо геморрой без цели).
Необходимо использовать метод "УстановитьПериодРассчитанныхИтогов()" - пересчитать можно, например, только несколько последних месяцев и не нагружать систему лишним пересчетом прошлых лет.
Подскажите пожалуйста, что именно делает "УстановитьПериодРассчитанныхИтогов"? Почему рекомендуется использовать этот метод, а не "ПересчитатьИтогиЗаПериод"?
Правильно ли я понимаю, что "ПересчитатьИтогиЗаПериод" обновит данные по месяцам за выбранный период?
Для MS SQL, как правило, используется сдвиг дат на 2000 лет вперед.
Обусловлено ограничениями MS SQL на минимальное значение даты.
Сейчас итоги пересчитываю два раза в неделю. Сама процедура занимает около 1,5 часа.
Я так понимаю, что чаще делать смысла нет?
(114) El_Loco, все записит от интенсивности работы пользователей. Если после пересчета итогов время выполнения запросов не уменьшается, то чаще делать нет смысла.. можно, наверное, даже реже.
Платформа 8.3 выгружает в dt итоги наряду с движениями. Соответственно при восстановлении базы из dt они не пересчитываются, а загружаются из файла.
(120) pisarevEV,
К сожалению, я уже не помню назначение эти файлов.
Если вы удалите эти файлы, а потом перепроведете абсолютно все документы в базе, то это не сильно поможет, т.к. в итогах все равно будут нулевые записи.
Нужен именно пересчет итогов.
1. пересчет итогов методом менеджера
2. сдвинуть границу итогов на 1900г, потом сдвигать вперед
Эти способы не помогают (8.2.19).
- показывается количество нулевых строк итогов и можно их удалять до заданного периода
- видно сколько строк итогов в каждом месяце
- можно очищать таблицы итогов
- можно выполнять все штатные операции с итогами
"1) отключаем всех пользователей и делаем бэкап базы средствами MSSQL;
2) генерируем запросы на очистку всех таблиц итогов по регистрам накопления:
В контексте базы данных выполняем запрос:
SELECT 'TRUNCATE TABLE ' + name FROM sys.tables
WHERE name like '_AccumRgT%'
Результат вывода копируем, вставляем в окно запроса и выполняем в контексте базы данных.
3) Запускаем пересчет итогов через Тестирование и исправление в Конфигураторе."
все встало на свои места.
Для каждого Рег из Метаданные.РегистрыНакопления Цикл
Если Рег.ВидРегистра = Метаданные.СвойстваОбъектов.ВидРегистраНакопления.Остатки Тогда
РегистрыНакопления[Рег.Имя].УстановитьПериодРассчитанныхИтогов(Дата1, Дата2);
РегистрыНакопления[Рег.Имя].ПересчитатьТекущиеИтоги();
КонецЕсли;
КонецЦикла; Показатьгде дата1 и дата2 где-то в начале периода ведения учета,
вполне себе хорошо справляется с проблемой, быстро и качественно,
без установки периода рассчитанных итогов база некорректные записи не пересчитывает, может конечно с недавних версий платформы, так как статья старая
Выполнение этой трудоемкой операции(пересчет итогов), при наличии современных высокопроизводительных ресурсов, должно ощутимо ускориться, по идее.
благодарю Вас. Возможно, я не прав, и что-то не так сделал, но из 42 гиг занятых базой, освободилось 17 гиг.
после проведения технологических работ по группе баз занимаемое место стало менее 30%
ПересчитатьИтоги();
ПересчитатьИтогиЗаПериод( , НачалоМесяца(ТекущаяДата()));
ПересчитатьТекущиеИтоги();
УстановитьПериодРассчитанныхИтогов(НачалоМесяца(ТекущаяДата()) - 1);
УстановитьИспользованиеТекущихИтогов(Флаг)
Читая справку невозможно понять тонкостей использования
Скрипт для быстрой индексации
Declare @command nvarchar(4000);
Declare @version nvarchar(12);
Declare @objectid int;
Declare @indexid int;
Declare @frag decimal
Begin
/*===== Database Index Defrag for SQL 2005 and upper =====
Script taken
*/
Declare @db_id int;
Declare @partitioncount bigint;
Declare @schemaname nvarchar(130);
Declare @objectname nvarchar(130);
Declare @indexname nvarchar(130);
Declare @partitionnum bigint;
Declare @partitions bigint;
Set @db_id = DB_ID(N'****тут вставить имя базы***');
Sel ect
object_id AS objectid,
index_id AS indexid,
partition_number AS partitionnum,
avg_fragmentation_in_percent AS frag
Into #work_to_do
Fr om sys.dm_db_index_physical_stats (@db_id, NULL, NULL , NULL, 'LIMITED')
Where avg_fragmentation_in_percent > 10.0 AND index_id > 0;
Declare partitions CURSOR FOR SEL ECT * FR OM #work_to_do;
Open partitions;
While (1=1)
Begin
FETCH NEXT
Fr om partitions
Into @objectid, @indexid, @partitionnum, @frag;
If @@FETCH_STATUS < 0 Break;
Sel ect @objectname = QUOTENAME(o.name), @schemaname = QUOTENAME(s.name)
Fr om sys.objects as o
JOIN sys.schemas as s ON s.schema_id = o.schema_id
Wh ere o.object_id = @objectid;
Select @indexname = QUOTENAME(name)
Fr om sys.indexes
Wh ere object_id = @objectid AND index_id = @indexid;
Select @partitioncount = count (*)
Fr om sys.partitions
Wh ere object_id = @objectid AND index_id = @indexid;
set @command = N'ALT ER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' SET (ALLOW_PAGE_LOCKS = ON, ALLOW_ROW_LOCKS = ON);'
Exec (@command);
IF @frag < 30.0 Set @command = N'ALT ER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REORGANIZE';
IF @frag >= 30.0 Set @command =N'ALT ER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REBUILD';
IF @partitioncount > 1 Set @command = @command + N' PARTITION=' + CAST(@partitionnum AS nvarchar(10));
Exec (@command);
Print N'Executed: ' + @command;
set @command = N'ALT ER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' SET (ALLOW_PAGE_LOCKS = OFF, ALLOW_ROW_LOCKS = ON);'
Exec (@command);
End;
Close partitions;
Deallocate partitions;
Dr op Table #work_to_do;
End
Показать* замечание - запускать надо в технологическое окно , когда пользователи с базой не работают
| Код |
|---|
Для каждого Рег из Метаданные.РегистрыНакопления Цикл
Если Рег.ВидРегистра = Метаданные.СвойстваОбъектов.ВидРегистраНакопления.Остатки Тогда
РегистрыНакопления[Рег.Имя].ПересчитатьТекущиеИтоги();
КонецЕсли;
КонецЦикла;
Для каждого Рег из Метаданные.РегистрыБухгалтерии Цикл
РегистрыБухгалтерии[Рег.Имя].ПересчитатьТекущиеИтоги();
КонецЦикла;
Показать полностью |
T-SQL скрипт ,
1 вариант можно оформить как процедуру и вызывать прямо из 1С
2 вариант , запускать по времени перед запуском кода пересчетов итогов, скрипт у меня отрабатывает примерно 8 секунд. Можно настроить JOB за пару минут до запуска кода пересчета итогов.
| Код |
|---|
Declare @command nvarchar(4000);
Begin
Declare @partitions bigint;
Declare @db_id int;
Set @db_id = DB_ID(N'******'); ---- тут вставить звездочек вставьте имя вашей базы
-- sеleсt , whеrе , FRОМ уберите пробел
sel ect 'truncate table '+name AS Command Into #work_to_del fr om sys.tables
where name like '_AccumRgT%';
Declare partitions CURSOR FOR select * fr om #work_to_del;
Open partitions;
While (1=1)
Begin
FETCH NEXT
Fr om partitions
Into @command;
If @@FETCH_STATUS < 0 Break;
Exec (@command);
Print N'Executed: ' + @command;
End;
Close partitions;
Deallocate partitions;
dr op Table #work_to_del; --- Drор убрать пробелы
End
Показать полностью |
Вообще очень интересная ситуация. Если посчитать сколько ПОЛЕЗНЫХ скриптов написано "сторонними разработчиками", то они превысят объём софта от 1С процентов на 200, а то и больше.
Рейтинг: 3713
Вы можете заказать платную консультацию или разработку у автора. Будет создан приватный заказ на «Бирже заказов» для автора.
№ 177171
Создание 10.03.13 23:48
Обновление 18.07.15 02:13
Просмотры 329105
Загрузки 0
Рейтинг
735
Комментарии 154
Код открыт Не указано
Рубрики Инструменты администратора БД
Кому
Системный администратор
,
Разработчик
Тип файла Нет файла
Платформа 1С:Предприятие 8
Конфигурация 1C:Бухгалтерия
Операционная система Не имеет значения
Страна Не имеет значения
Отрасль Не имеет значения
Налоги Не имеет значения
Вид учета Не имеет значения
Доступ к файлу Бесплатно (free)