Каталог решений - Удаление лишних данных

Удаление лишних данных

Удаление лишних данных

В наличии

Настало то время, когда на SSD винчестерах размером 120 Гб начало заканчиваться место.  В связи с этим, было принято решение проанализиривать возможность уменьшения занимаемого места БД. Без веского обоснования у нас никакие работы не производятся, просто так оптимизацией никто заниматься не даст.
1. Выявление таблиц БД, занимающих много места.
2. Очистка записей регистров накопления.
3. Тестирование.

Категория:

Описание

Выявление таблиц БД, занимающих много места.

Для начала я решил выяснить, какие данные занимают много места. Хотел решить этот вопрос по-простому — скачать обработку с Infostart. По-простому получилось как-то не очень просто, оказалось, надо еще с обработкой разбираться. При помощи MS SQL, на мой взгляд, намного проще.

1. Выполняем запрос на MS SQL

USE [DatabaseName]
GO
CREATE TABLE #temp (
table_name sysname ,
row_count INT,
reserved_size VARCHAR(50),
data_size VARCHAR(50),
index_size VARCHAR(50),
unused_size VARCHAR(50))
SET NOCOUNT ON
INSERT #temp
EXEC sp_msforeachtable 'sp_spaceused ''?'''
SELECT a.table_name,
a.row_count,
COUNT(*) AS col_count,
a.data_size,
a.index_size 
FROM #temp a
INNER JOIN information_schema.columns b
ON a.table_name collate database_default
= b.table_name collate database_default
GROUP BY a.table_name, a.row_count, a.data_size, a.index_size
ORDER BY CAST(REPLACE(a.data_size, ' KB', '') AS integer) DESC
DROP TABLE #temp

Вместо [DatabaseName] нужно подставить название нужной базы.

2. Результат запроса прекрасно копируется в MS Excel. С помощью функции » ПОДСТАВИТЬ » избавляемся от » KB», и преобразуем значения из строк в числа. 

3. Вычисляем процент от занимаемого места.

4. По названию таблиц определям метаданные. 

тзСтруктураХранения = ПолучитьСтруктуруХраненияБазыДанных(,);
СтруктураОтбора = Новый Структура("ИмяТаблицыХранения", НазваниеТаблицы);
мстзСтруктураХранения = тзСтруктураХранения.НайтиСтроки(СтруктураОтбора);
	
тзРезультат = тзСтруктураХранения.Скопировать(мстзСтруктураХранения);
	
Для Каждого стзРезультат Из тзРезультат Цикл
	Сообщить("" + стзРезультат.Метаданные + "	" + стзРезультат.Назначение);
КонецЦикла;

В моем случае, получился результат, приведенный в таблице:

результат

Учет НДС (книги покупок/ продаж) в данной базе не ведется. Расчет с контрагентами (не путать со взаиморасчетами) также не ведется. Результат мы видим в таблице — регистры превратились в свалку.

Очистка записей регистров накопления

План работ:

  1. Внести изменения в алгоритмы, делающие записи по регистрам, которые нужно очистить.
  2.  Очистка регистров.
  3. Тестирование.

Изменение алгоритмов

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

Остановился на следующем методе. 

  • Выписал все возможные регистраторы (документы);
  • В каждом документе анализировал проведение документа.

Такой метод оказался намного проще, естественно, не даёт гарантированный 100% результат.

Очистка регистров

Для очистки регистров написал следующую обработку:

Процедура ОчиститРегистр(НаименованиеРегистра)
	Запрос = Новый Запрос();
	Запрос.Текст =
	"ВЫБРАТЬ РАЗЛИЧНЫЕ
	|	" + НаименованиеРегистра + ".Регистратор,
	|	" + НаименованиеРегистра + ".Период КАК Период
	|ИЗ
	|	РегистрНакопления." + НаименованиеРегистра + " КАК " + НаименованиеРегистра + "
	|
	|УПОРЯДОЧИТЬ ПО
	|	Период УБЫВ";
	
    Выборка = Запрос.Выполнить().Выбрать();
	Индикатор = 0;
	ЭлементыФормы.Индикатор.МаксимальноеЗначение = Выборка.Количество();
	Пока Выборка.Следующий() Цикл
		нзРегистр = РегистрыНакопления[НаименованиеРегистра].СоздатьНаборЗаписей();
		нзРегистр.Отбор.Регистратор.Значение = Выборка.Регистратор;
		нзРегистр.Записать();		
		Индикатор = Индикатор + 1;
	КонецЦикла;	
	
	РегистрыНакопления[НаименованиеРегистра].ПересчитатьИтоги();
КонецПроцедуры

Процедура КнопкаВыполнитьНажатие(Кнопка)
	// Вставить содержимое обработчика.
	СписокРегистров = Новый Массив();
	СписокРегистров.Добавить("НДСРасчетыСПокупателями");
	СписокРегистров.Добавить("НДСРасчетыСПоставщиками");
	СписокРегистров.Добавить("РасчетыСКонтрагентами");
	СписокРегистров.Добавить("НДСПредъявленный");
	
	ЭлементыФормы.Индикатор1.МаксимальноеЗначение = 4;
	Индикатор1 = 0;
	Для Каждого НаименованиеРегистра Из СписокРегистров Цикл
		Индикатор1 = Индикатор1 + 1;
		ОчиститРегистр(НаименованиеРегистра);	
	КонецЦикла;
	
КонецПроцедуры

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

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

Тестирование

Тестирование я проводил следующим образом.

  • Перепроводил документы (за месяц);
  • Проверка на наличие записей в регистрах;
  • Проверка изменения остатков.

При правке кода для удаления проведения по регистру «Расчеты с покупателями», была возможность повредить код проведения по регситру «Заявки на расходование средств». Поэтому я решил проконтролировать остатки по данному регистру следующим образом:

  1. Остатки по регистру выгрузил в файл.
  2. Перепровел документы.
  3. Сравнил остатки в файле с  остатками в базе.

Код обработки:

Перем ТипДиалога;


Процедура ВыбФайлНачалоВыбора(Элемент, СтандартнаяОбработка)
	// Вставить содержимое обработчика.
	длгВыборФайла = Новый ДиалогВыбораФайла(ТипДиалога);
	Если длгВыборФайла.Выбрать() Тогда
		ВыбФайл = длгВыборФайла.ПолноеИмяФайла;		
	КонецЕсли;	
КонецПроцедуры

Процедура СохранитьНажатие(Элемент)
	// Вставить содержимое обработчика.
	Запрос = Новый Запрос();
	Запрос.Текст =
	"ВЫБРАТЬ
	|	ЗаявкиНаРасходованиеСредствОстатки.ДоговорКонтрагента,
	|	ЗаявкиНаРасходованиеСредствОстатки.Сделка,
	|	ЗаявкиНаРасходованиеСредствОстатки.ЗаявкаНаРасходование,
	|	ЗаявкиНаРасходованиеСредствОстатки.СтатьяДвиженияДенежныхСредств,
	|	ЗаявкиНаРасходованиеСредствОстатки.Проект,
	|	ЗаявкиНаРасходованиеСредствОстатки.СуммаВзаиморасчетовОстаток,
	|	ЗаявкиНаРасходованиеСредствОстатки.СуммаУпрОстаток,
	|	ЗаявкиНаРасходованиеСредствОстатки.СуммаОстаток
	|ИЗ
	|	РегистрНакопления.ЗаявкиНаРасходованиеСредств.Остатки КАК ЗаявкиНаРасходованиеСредствОстатки";
	
	
	тзОстатки = Запрос.Выполнить().Выгрузить();
	ЗначениеВФайл(ВыбФайл, тзОстатки);	
КонецПроцедуры

Процедура СравнитьНажатие(Элемент)
	// Вставить содержимое обработчика.
	Запрос = Новый Запрос();
	Запрос.Текст =
	"ВЫБРАТЬ
	|	ЗаявкиНаРасходованиеСредствОстатки.ДоговорКонтрагента,
	|	ЗаявкиНаРасходованиеСредствОстатки.Сделка,
	|	ЗаявкиНаРасходованиеСредствОстатки.ЗаявкаНаРасходование,
	|	ЗаявкиНаРасходованиеСредствОстатки.СтатьяДвиженияДенежныхСредств,
	|	ЗаявкиНаРасходованиеСредствОстатки.Проект,
	|	-ЗаявкиНаРасходованиеСредствОстатки.СуммаВзаиморасчетовОстаток КАК СуммаВзаиморасчетовОстаток,
	|	-ЗаявкиНаРасходованиеСредствОстатки.СуммаУпрОстаток КАК СуммаУпрОстаток,
	|	-ЗаявкиНаРасходованиеСредствОстатки.СуммаОстаток КАК СуммаОстаток
	|ИЗ
	|	РегистрНакопления.ЗаявкиНаРасходованиеСредств.Остатки КАК ЗаявкиНаРасходованиеСредствОстатки";
	
	
	тзРезультат = Запрос.Выполнить().Выгрузить();
	
	тзОстатки = ЗначениеИзФайла(ВыбФайл);
	
	Для Каждого стзОстатки Из тзОстатки Цикл
		стзРезультат = тзРезультат.Добавить();
		ЗаполнитьЗначенияСвойств(стзРезультат, стзОстатки);
	КонецЦикла;
	
	тзРезультат.Свернуть("ДоговорКонтрагента,Сделка,ЗаявкаНаРасходование,СтатьяДвиженияДенежныхСредств,Проект", "СуммаВзаиморасчетовОстаток,СуммаУпрОстаток,СуммаОстаток");
	Сч = тзРезультат.Количество();
	Пока Сч > 0 Цикл
		Сч = Сч - 1;
		стзРезультат = тзРезультат[Сч];
		Если стзРезультат.СуммаВзаиморасчетовОстаток = 0 
			И стзРезультат.СуммаУпрОстаток = 0 
			И стзРезультат.СуммаОстаток = 0  Тогда
			тзРезультат.Удалить(стзРезультат);
		КонецЕсли;
	КонецЦикла;
	
	тзРезультат.ВыбратьСтроку();
	
КонецПроцедуры


ТипДиалога = РежимДиалогаВыбораФайла.Открытие;

Заключение

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

has been added to your cart:
Оформление заказа