Восстановление индексов СУБД

09.10.19

Задачи пользователя - Корректировка данных

Восстановление индексов СУБД на основе структуры хранения базы данных 1С.

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

"У нас ничего не работает!!"

"База тормозит!!"

Ну что могло случиться на выходных? Все работало и вдруг перестало.

Ознакомившись с работой пользователей, выяснил, что основная масса запросов идет к регистрам с распухшим (для текущей ситуации) количеством записей - четыре регистра накопления с количеством от 1,5 до 46 млн. записей.

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

Ну и как вы наверное уже догадались, для большинства объектов базы 1С в СУБД физически не существовало индексов, что и показала нам MS SQL Studio. В связи с чем, это могло произойти так и не понял. Причем индексов не было на двух базах MSSQL. Есть подозрения, что базы входили в режим восстановления, возможно это и явилось причиной.

Первым пришедшим на ум решением, было достать описание метаданных (скрипт создания) из "живых" СУБД с наличием индексов и позаимствовав оттуда скрипты создания индексов просто выполнить их в "больных" базах. Но опыта работы с MS SQL не очень много, и данные потуги потерпели фиаско. В итоге пришла мысль создать скрипты создания индексов из структуры хранения базы данных 1С.

В связи с этим на свет и появился код для "Инструментов разработчика", коим и поспешил поделиться с сообществом.

 

//*********************************
// ОБЩИЕ ПЕРЕМЕННЫЕ
ИмяБазыСУБД = "MyBASE";
ВыводитьСтатусОперации = Истина;

// для получения только отсутствующих в СУБД
ТолькоОтсутствующиеВСУБД = Истина;
ИмяСервераСУБД = "MyServer";
ИмяПользователяСУБД = "sa";
ПарольПользователяСУБД = "MyPassword";
//*********************************

Состояние("Получаем структуру хранения базы данных...");
СХД= ПолучитьСтруктуруХраненияБазыДанных(,Истина); // по всем объектам, в терминах СУБД

Состояние("Заполняем таблицу данных для создания индексов...");

ТЗИнд = Новый ТаблицаЗначений;
ТЗИнд.Колонки.Добавить("ИмяИндекса");        					// имя индекса из СХД
ТЗИнд.Колонки.Добавить("ИмяТаблицы");        					// имя таблицы 1С
ТЗИнд.Колонки.Добавить("ИмяМетаданного"); 					// метаданные из СХД
ТЗИнд.Колонки.Добавить("ПоляИндекса");  						// таблица значений из СХД
ТЗИнд.Колонки.Добавить("ПоляИндексаСтрокой");  		// все поля собрали в строку
ТЗИнд.Колонки.Добавить("Кластеризованный"); 				// кластеризованный или нет
ТЗИнд.Колонки.Добавить("СтрокаСоздания"); 					// строка для создания индекса в СУБД

Для Каждого СтрокаСХД Из СХД Цикл
	Для Каждого СтрокаИндексаСХД Из СтрокаСХД.Индексы Цикл
		ИмяМетаданного = СтрокаСХД.ИмяТаблицыХранения;
		ИмяИндексаХранения = СтрокаИндексаСХД.ИмяИндексаХранения;
		
		СтрокаИнд = ТЗИнд.Добавить();
		СтрокаИнд.ИмяМетаданного = ИмяМетаданного;
		СтрокаИнд.ИмяИндекса = ИмяИндексаХранения;
		СтрокаИнд.ПоляИндекса = СтрокаИндексаСХД.Поля;
		СтрокаИнд.ИмяТаблицы = СтрокаСХД.ИмяТаблицы;
		
		// собрали поля индекса в строку
		ПоляИндексаСтрокой = "";
		Для Каждого СтрокаИмениПоля из СтрокаИнд.ПоляИндекса Цикл
			ПоляИндексаСтрокой = ПоляИндексаСтрокой+?(ПустаяСтрока(ПоляИндексаСтрокой),"",", ")+СтрокаИмениПоля.ИмяПоляХранения;
		КонецЦикла;	
		СтрокаИнд.ПоляИндексаСтрокой = ПоляИндексаСтрокой;
		 
		// вид индекса кластерный или нет - из копии оставшей СУБД или по имени индекса
		СтрокаИнд.Кластеризованный = 0;				
		Если Найти(ИмяИндексаХранения,"PK__") > 0 или                   // первичный для всех
				Найти(ИмяИндексаХранения,"_IntKeyInd") > 0 или 		 	// для табличных частей документов
				Найти(ИмяИндексаХранения,"_ByDataKey_") > 0  или     // 
				Найти(ИмяИндексаХранения,"_TRN") > 0 							// для регистров
				Тогда				
				СтрокаИнд.Кластеризованный = 1;				
				
		КонецЕсли;		
			
	КонецЦикла;	
	
КонецЦикла;	

// получим индексы из СУБД
СоответствиеИндексов = Новый Соответствие;
Если ТолькоОтсутствующиеВСУБД тогда
	Состояние("Получаем индексы СУБД ...");
	
	СтрокаСоединения = "Provider=SQLOLEDB; Data Source="""+ИмяСервераСУБД+"""; Initial Catalog="""+ИмяБазыСУБД+"""; User Id="""+ИмяПользователяСУБД+"""; Password="""+ПарольПользователяСУБД+"""";
	Соединение = Новый COMОбъект("ADODB.Connection");
	Соединение.ConnectionString = СтрокаСоединения;
	Соединение.Open();

	Команда = Новый COMОбъект("ADODB.Command");
	Команда.ActiveConnection = Соединение;
	Команда.CommandText = "select name, type from sys.indexes where type <> 0";
	Данные = Команда.Execute();

	Данные.MoveFirst();
	Пока НЕ Данные.EOF Цикл
		ИмяИндекса = Данные.Fields.Item(0).Value;
		СоответствиеИндексов.Вставить(ИмяИндекса,ИмяИндекса);
		Данные.MoveNext();
	КонецЦикла;	
КонецЕсли;

// собираем строку создания индекса на стороне СУБД
// https://docs.microsoft.com/ru-ru/sql/t-sql/statements/create-index-transact-sql?view=sql-server-2017
// Создавайте кластеризованные индексы до создания любых некластеризованных. 
// При создании кластеризованного индекса все существующие некластеризованные индексы таблицы перестраиваются.
ТЗИнд.Сортировать("ИмяТаблицы Возр,Кластеризованный Убыв");
КоличествоСтрок = ТЗИнд.Количество();
Ном =1;

Состояние("Получаем финальный скрипт...");
СтрокаСкрипта = "use "+ИмяБазыСУБД+" GO";
Для Каждого СтрокаИнд Из ТЗИнд Цикл
	    ИмяИндекса  = СтрокаИнд.ИмяИндекса;
		
		ИндексЕстьВСУБД = Ложь;
		Если ТолькоОтсутствующиеВСУБД тогда
			ИндексЕстьВСУБД = СоответствиеИндексов.Получить(ИмяИндекса) <> Неопределено;
		КонецЕсли;
		
		Если ИндексЕстьВСУБД тогда
			Продолжить;
		КонецЕсли;
		
		СтрокаСоздания = "";
		// статус операции для наглядности
		Если ВыводитьСтатусОперации тогда
			СтрокаСтатуса =  Строка(Ном)+" из "+Строка(КоличествоСтрок) + " ("+Формат(Ном*100/КоличествоСтрок,"ЧЦ=4; ЧДЦ=2; ЧГ=0")+"%)";
			СтрокаСоздания = "Print('"+СтрокаСтатуса +". "+СтрокаИнд.ИмяТаблицы+"')"+Символы.ПС; 			// выведем имя таблицы 1С
		КонецЕсли;	
		//--
		
		СтрокаСоздания = СтрокаСоздания +"CREATE UNIQUE " + ?(СтрокаИнд.Кластеризованный = 1," CLUSTERED ","")+ " INDEX "         		// имя индекса
										+ ИмяИндекса+Символы.ПС+" ON ["+ИмяБазыСУБД+"].dbo.["+СтрокаИнд.ИмяМетаданного+"] ("        // имя метаданного SQL
										+ СтрокаИнд.ПоляИндексаСтрокой +") "+ "WITH (DROP_EXISTING = OFF) "                                                                   // поля индекса
										+ "  ON [PRIMARY] "
										+Символы.ПС+"GO";									
		СтрокаИнд.СтрокаСоздания = СтрокаСоздания; 					
		
		СтрокаСкрипта = СтрокаСкрипта+?(ПустаяСтрока(СтрокаСкрипта),"", Символы.ПС)+ СтрокаСоздания;
		
		Ном = Ном + 1;
КонецЦикла;

// добавили в скрипт обновление статистики и чистку кэша
СтрокаСкрипта = СтрокаСкрипта + Символы.ПС
							+" EXEC sp_updatestats;"+Символы.ПС
							+ "DBCC FREEPROCCACHE";

 

Результат выполнения - строка, которую использовал в MS SQL Studio, чтобы отслеживать прогресс выполнения создания индексов.

 

UPD 1.

В код добавлена возможность создавать только отсутствующие в СУБД индексы. Для этого используем подключение ADO и анализ имеющихся в СУБД индексов.

Регулируется параметром "ТолькоОтсутствующиеВСУБД " в шапке кода.

См. также

Корректировка данных Зарплата Бухгалтер Платформа 1С v8.3 Сложные периодические расчеты 1С:Зарплата и кадры бюджетного учреждения 1С:Зарплата и Управление Персоналом 3.x Россия Бухгалтерский учет НДФЛ Платные (руб)

Обработка исправляет технические ошибки по НДФЛ, взаиморасчетам с сотрудниками в 1С:ЗУП (1С:ЗКГУ) на начало года. Фактически все ошибки, которые проявляются в ведомостях на выплату, расчетных листках, при заполнении ведомостей на выплату и отчетах 6-НДФЛ и т.д. нужно начинать исправлять с начала расчетного года. Это позволит быть уверенными, что после завершения расчетов предыдущего года, начали работать с «чистого листа» без ошибочных остатков.

60000 руб.

06.10.2023    4513    37    18    

45

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

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

14400 руб.

29.04.2020    33825    108    152    

75

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

Незаменимая обработка для сопровождения конфигураций: ERP, УТ, КА. Позволяет вычистить многие ошибки в ключах аналитики, в ключевых справочниках конфигурации.

3600 руб.

10.02.2017    111381    669    174    

708

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

Представьте, что есть система QR - кодирования, которая НЕ ТРЕБУЕТ изменения конфигурации, НЕ ТРЕБУЕТ изменения ни одной печатной формы для добавления QR-кода, включая внешние, НЕ ХРАНИТ данные штрихкодов и их связь, от чего база не "пухнет", ИМЕЕТ возможность закодировать в QR-коде произвольные данные параметров для последующей обработки полученных данных, УМЕЕТ прикреплять сканы, УМЕЕТ обработать считанный QR-код как ВЫ захотите. А также ХРАНИТ историю операций в обход базы для каждого пользователя в отдельности и УМЕЕТ работать с 2D - сканерами. А также автоматически распознавать отсканированные печатные формы (картинки или pdf-файлы) и выполнять заданные произвольные алгоритмы, в том числе прикрепление их к документам! Обновление 3.2 от 09.06.2024!

19200 руб.

26.08.2018    52618    16    61    

55

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

Вы наконец разобрались с закрытием месяцев и пора начать контролировать сроки оплаты поставщикам и задолженности клиентов, но в базе расчеты не идут из-за развернутого сальдо? Не беда, есть решение!

12000 руб.

02.11.2020    7537    6    0    

8

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

Внешняя обработка, позволяющая произвольным образом заполнять документ "Корректировка регистров" Предназначена для использования в конфигурациях "Управление торговлей 11", "Управление небольшой фирмой", "ERP Управление предприятием", а также в других конфигурациях, в состав которых входит библиотека стандартных подсистем (БСП) версии 2.2+ и указанный выше документ.

2400 руб.

13.07.2015    51367    175    29    

127

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

Обработка предназначена для ООО для смены системы налогообложения УСН на ОСНО, без ведения раздельного учета, входящего НДС по способам учета. При реализации перехода в операции формируются проводки по выделению НДС, который ранее учитывался в стоимости номенклатуры, регистр «НДС Предъявленный».

6000 руб.

22.01.2025    278    1    0    

3

Корректировка данных Бухгалтер Платформа 1С v8.3 Бухгалтерский учет 1С:Бухгалтерия 3.0 Бухгалтерский учет Налоговый учет Налог на прибыль Платные (руб)

Обработка служит для: выравнивания бухгалтерского и налогового учета на определенную дату по выбранным счетам; закрытия остатков по выбранным счетам; обнуления налогового учета (ПР, ВР также будут обнулены)

2880 руб.

05.05.2024    702    10    0    

6
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. triviumfan 98 15.10.19 09:04 Сейчас в теме
ТиИ -> Реиндексация?
2. Pixar0000 18.10.19 14:52 Сейчас в теме
"собираем строку создания индекса на стороне СУБД"
профанация и бред
3. пользователь 31.07.22 17:10
Сообщение было скрыто модератором.
...
Оставьте свое сообщение