Вам также могут быть интересны:
Сжатие баз данных 1С: Как оптимизировать хранение и избежать ошибок?
Объемы данных, которые требуются компаниям ежедневно для анализа и прогнозирования своей деятельности, постоянно растут. Поэтому одним из вполне логичных действий является сжатие баз данных, в частности – одного из самых популярных семейств ПО для управления бизнесом и ведения учета – 1С. Подобная процедура позволяет уменьшить размер хранимых баз данных, снизить нагрузку на дисковую подсистему, а также избежать необходимости приобретения новых дисковых емкостей.
Однако на практике, когда 1С работает с базами данных, необходимо приложить дополнительные усилия для компрессии информации. Дело в том, что при реструктуризации новые таблицы и индексы оказываются несжатыми. А реструктуризация может быть вызвана разными операциями – например, обновление на новый релиз конфигурации или проведение полного тестирования и исправления информационной базы. Это связано с тем, что параметр компрессии указывается отдельно для каждого индекса и таблицы.
Решение вопроса для MS SQL Server
Чтобы обеспечить перманентное сжатие всей базы данных, необходимо отследить моменты, когда создается новая таблица или индекс и присвоить данному объекту параметр «сжатие» до начала переноса данных платформой 1С. Для этого необходимо использовать DDL-триггер, причем лучше сразу для всего сервера, а не для отдельной базы данных – это больше соответствует лицензионной политике 1С.
Чтобы выполнить сжатие таблицы нужно выполнить команду
ALTER TABLE [имя базы].[имя схемы].[имя таблицы] REBUILD PARTITION = ALL WITH (DATA_COMPRESSION = PAGE).
В случае с индексом все происходит точно также:
ALTER INDEX [имя индекса] ON [имя базы].[имя схемы].[имя таблицы] REBUILD PARTITION = ALL WITH (DATA_COMPRESSION = PAGE).
Поэтому триггеры будут иметь примерно следующий вид:
CREATE TRIGGER [data_compression] ON ALL SERVER AFTER CREATE_TABLE AS ...текст триггера
CREATE TRIGGER [index_compression] ON ALL SERVER AFTER CREATE_INDEX AS ...текст триггера
Пример реализации
Чтобы получить большую гибкость в настройках, можно также создать отдельную базу данных (назовем ее CompressionSettings), которая будет хранить информацию о тех база данных на сервере, которые не подлежат сжатию, а также содержать таблицу с логом для мониторинга работы триггеров. Для этого можно использовать следующий код:
CREATE TABLE [dbo].[Databases]( [name] [nvarchar](100) NULL, [active] [int] NULL) ON [PRIMARY] GO CREATE TABLE [dbo].[trace]( [text] [nvarchar](max) NULL, [DatabaseName] [nvarchar](max) NULL, [DateTime] [datetime] NULL) ON [PRIMARY]
Ниже приведены примеры триггеров для индексов и для таблиц, которые уже были проверены в работе:
CREATE TRIGGER [data_compression] ON ALL SERVER AFTER CREATE_TABLE AS DECLARE @SchemaName nvarchar(150), @ObjectName nvarchar(150), @DatabaseName nvarchar(150), @cmd nvarchar(150) --Получим имя схемы из выполняемой команды CREATE TABLE SET @SchemaName = EVENTDATA().value('(/EVENT_INSTANCE/SchemaName)[1]','nvarchar(150)') --Получим имя таблицы SET @ObjectName = EVENTDATA().value('(/EVENT_INSTANCE/ObjectName)[1]','nvarchar(150)') --Получим имя базы SET @DatabaseName = EVENTDATA().value('(/EVENT_INSTANCE/DatabaseName)[1]','nvarchar(150)') --Сформируем из полученных данных требуемую команду на установку признака сжатия для таблицы set @cmd = 'ALTER TABLE [' + @DatabaseName + '].[' + @SchemaName + '].[' + @ObjectName + '] REBUILD PARTITION = ALL WITH (DATA_COMPRESSION = PAGE)' --Теперь проверяем настройки – если базы нет в таблице CompressionSetting.dbo.Databases с признаком Active = 1, то выполняем команду, иначе игнорируем IF NOT EXISTS (SELECT 1 AS Expr1 FROM CompressionSetting.dbo.Databases AS T WHERE (name = @DatabaseName) AND Active = 1) BEGIN INSERT INTO CompressionSetting.dbo.trace (text, DatabaseName, DateTime) SELECT @cmd, @DatabaseName, GETDATE() EXEC (@cmd) END ELSE BEGIN PRINT 'TEST' END
CREATE TRIGGER [index_compression] ON ALL SERVER AFTER CREATE_INDEX AS DECLARE @SchemaName nvarchar(150), @ObjectName nvarchar(150), @TargetObjectName nvarchar(150), @DatabaseName nvarchar(150), @cmd nvarchar(150) --Получим имя схемы из выполняемой команды CREATE INDEX SET @SchemaName = EVENTDATA().value('(/EVENT_INSTANCE/SchemaName)[1]','nvarchar(150)') --Получим имя индекса SET @ObjectName = EVENTDATA().value('(/EVENT_INSTANCE/ObjectName)[1]','nvarchar(150)') --Получим имя таблицы SET @TargetObjectName = EVENTDATA().value('(/EVENT_INSTANCE/TargetObjectName)[1]','nvarchar(150)') --Получим имя базы SET @DatabaseName = EVENTDATA().value('(/EVENT_INSTANCE/DatabaseName)[1]','nvarchar(150)') --Сформируем из полученных данных требуемую команду на установку признака сжатия для индекса set @cmd = 'ALTER INDEX [' + @ObjectName + '] ON [' + @DatabaseName + '].[' + @SchemaName + '].[' + @TargetObjectName + '] REBUILD PARTITION = ALL WITH (DATA_COMPRESSION = PAGE)' --Теперь проверяем настройки – если базы нет в таблице CompressionSetting.dbo.Databases с признаком Active = 1, то выполняем команду, иначе игнорируем IF NOT EXISTS (SELECT 1 AS Expr1 FROM CompressionSetting.dbo.Databases AS T WHERE (name = @DatabaseName) AND Active = 1) BEGIN INSERT INTO CompressionSetting.dbo.trace (text, DatabaseName, DateTime) SELECT @cmd, @DatabaseName, GETDATE() EXEC (@cmd) END ELSE BEGIN PRINT 'TEST' END
Сжатие имеющихся баз данных
Как вы понимаете, триггеры ловят момент создания новой таблицы или индекса. А это значит, что они будут эффективны только для новых таблиц и индексов, но для компрессии уже существующих баз данных необходимо применить дополнительные меры. В качестве наиболее оптимального варианта можно рекомендовать заново создать базу данных через dt-файл. При этом она будет минимального размера, а время загрузки БД со сжатием будет практически таким же, как в обычном режиме. Также существует возможность выполнить полную реструктуризацию базы данных или написать скрипт для перебора всех таблиц и индексов, но это занимает длительное время, а также требует последующего применения SHRINK DATABASE для уменьшения раздувшейся базы данных.