Форум OlegON > Программы и оборудование для автоматизации торговли > Системы автоматизации торговли > Бэк-офисы платформы 1С > 1С: Бухгалтерия

Время выполнения отчёта в зависимости от прав пользователя : 1С: Бухгалтерия

28.03.2024 17:27


13.06.2013 09:43
KirillHome
 
Обнаружил странную штуку - если пользователь не обладает ролью "Полные права", то скорость выполнения такого запроса
[spoil=Текст запроса]
Код:
	ЗапросДвижений = Новый Запрос;
	ЗапросДвижений.Текст = 
		"ВЫБРАТЬ
		|	ХозрасчетныйДвиженияССубконто.СчетДт КАК СчетДт,
		|	ХозрасчетныйДвиженияССубконто.СубконтоДт1 КАК СубконтоДт1,
		|	ХозрасчетныйДвиженияССубконто.СубконтоДт2,
		|	ХозрасчетныйДвиженияССубконто.СубконтоДт3,
		|	ХозрасчетныйДвиженияССубконто.СчетКт,
		|	ХозрасчетныйДвиженияССубконто.СубконтоКт1,
		|	ХозрасчетныйДвиженияССубконто.СубконтоКт2,
		|	ХозрасчетныйДвиженияССубконто.СубконтоКт3,
		|	ХозрасчетныйДвиженияССубконто.Организация,
		|	ХозрасчетныйДвиженияССубконто.Сумма
		|ИЗ
		|	РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто(
		|			&ДатаНачала,
		|			&ДатаЗавершения,
		|			Организация = &Организация
		|				И Регистратор.Ссылка = &Регистратор,
		|			,
		|			) КАК ХозрасчетныйДвиженияССубконто";
		
		
	ЗапросРучныеОперации = Новый Запрос;
	ЗапросРучныеОперации.Текст = 
		 "ВЫБРАТЬ
		 |	ОперацияБух.Ссылка КАК Ссылка,
		 |	ОперацияБух.Дата КАК Дата
		 |ИЗ
		 |	Документ.ОперацияБух КАК ОперацияБух
		 |ГДЕ
		 |	ОперацияБух.Дата >= &ДатаНачала
		 |	И ОперацияБух.Дата <= &ДатаЗавершения
		 |	И ОперацияБух.ПометкаУдаления = &ПометкаУдаления
		 |	И ОперацияБух.Организация = &Организация
		 |";
	
	ЗапросРучныеОперации.УстановитьПараметр("ДатаНачала", НачалоДня(РеквизитДатаНачала));
	ЗапросРучныеОперации.УстановитьПараметр("ДатаЗавершения", КонецДня(РеквизитДатаЗавершения));
	ЗапросРучныеОперации.УстановитьПараметр("Организация", РеквизитОрганизация);
	ЗапросРучныеОперации.УстановитьПараметр("ПометкаУдаления", Ложь);
	
	Результат = ЗапросРучныеОперации.Выполнить();
	ВыборкаДетальныеЗаписи = Результат.Выбрать();

	Пока ВыборкаДетальныеЗаписи.Следующий() Цикл

		ЗапросДвижений.УстановитьПараметр("ДатаНачала", НачалоДня(ВыборкаДетальныеЗаписи.Дата));
		ЗапросДвижений.УстановитьПараметр("ДатаЗавершения", КонецДня(ВыборкаДетальныеЗаписи.Дата));
		ЗапросДвижений.УстановитьПараметр("Регистратор", ВыборкаДетальныеЗаписи.Ссылка);
		ЗапросДвижений.УстановитьПараметр("Организация", РеквизитОрганизация);
		РезультатДвижений = ЗапросДвижений.Выполнить();
		ВыборкаДвижений = РезультатДвижений.Выбрать();
		Пока ВыборкаДвижений.Следующий() Цикл
			Если ВыборкаДвижений.СубконтоДт1 = РеквизитБезНал и ВыборкаДвижений.СубконтоДт2 = РеквизитДоговор Тогда
				СтрокаДобавления = ТабличнаяЧастьРезультатов.Добавить();
				СтрокаДобавления.РеквизитТЧРезультатовДата = НачалоДня(ВыборкаДетальныеЗаписи.Дата);
				Если ВыборкаДвижений.Сумма > 0 Тогда
					СтрокаДобавления.РеквизитТЧРезультатовСуммаБН = ВыборкаДвижений.Сумма;
					СтрокаДобавления.РеквизитТЧРезультатовСуммаБНВозвр = 0;
				Иначе
					СтрокаДобавления.РеквизитТЧРезультатовСуммаБН = 0;
					СтрокаДобавления.РеквизитТЧРезультатовСуммаБНВозвр = (-1)*ВыборкаДвижений.Сумма;
				КонецЕсли;
			ИначеЕсли ВыборкаДвижений.СубконтоКт1 = РеквизитБезНал и ВыборкаДвижений.СубконтоКт2 = РеквизитДоговор Тогда
				Если ВыборкаДвижений.Сумма > 0 Тогда
					СтрокаДобавления.РеквизитТЧРезультатовСуммаБН = 0;
					СтрокаДобавления.РеквизитТЧРезультатовСуммаБНВозвр = (-1)*ВыборкаДвижений.Сумма;
				Иначе
					СтрокаДобавления.РеквизитТЧРезультатовСуммаБН = (-1)*ВыборкаДвижений.Сумма;
					СтрокаДобавления.РеквизитТЧРезультатовСуммаБНВозвр = 0;
				КонецЕсли;
			КонецЕсли;
		КонецЦикла;
	КонецЦикла;
[/spoil]
увеличивается весьма и весьма значительно (роль "полные права" доступна - 1 секунда, роль "полные права" не доступна - 45-50 секунд, и это при условии - что данных не так уж и много).

Выход - не обращаться к регистру ХозрасчетныйДвиженияССубконто через запрос, а выбирать данные через "НаборЗаписей"
[spoil=Изменённый текст запроса]
Код:
	ЗапросРучныеОперации = Новый Запрос;
	ЗапросРучныеОперации.Текст = 
		 "ВЫБРАТЬ
		 |	ОперацияБух.Ссылка КАК Ссылка,
		 |	ОперацияБух.Дата КАК Дата
		 |ИЗ
		 |	Документ.ОперацияБух КАК ОперацияБух
		 |ГДЕ
		 |	ОперацияБух.Дата >= &ДатаНачала
		 |	И ОперацияБух.Дата <= &ДатаЗавершения
		 |	И ОперацияБух.ПометкаУдаления = &ПометкаУдаления
		 |	И ОперацияБух.Организация = &Организация
		 |";
	
	ЗапросРучныеОперации.УстановитьПараметр("ДатаНачала", НачалоДня(РеквизитДатаНачала));
	ЗапросРучныеОперации.УстановитьПараметр("ДатаЗавершения", КонецДня(РеквизитДатаЗавершения));
	ЗапросРучныеОперации.УстановитьПараметр("Организация", РеквизитОрганизация);
	ЗапросРучныеОперации.УстановитьПараметр("ПометкаУдаления", Ложь);
	
	Результат = ЗапросРучныеОперации.Выполнить();
	ВыборкаДетальныеЗаписи = Результат.Выбрать();
    
	НаборЗаписей = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
	Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
		
		НаборЗаписей.Отбор.Регистратор.Установить(ВыборкаДетальныеЗаписи.Ссылка);
		НаборЗаписей.Прочитать();
		Если НаборЗаписей.Количество() > 0 Тогда
			Для Каждого Запись из НаборЗаписей Цикл
				Если Запись.СубконтоДт.Контрагенты = РеквизитБезНал и Запись.СубконтоДт.Договоры = РеквизитДоговор Тогда
					СтрокаДобавления = ТабличнаяЧастьРезультатов.Добавить();
					СтрокаДобавления.РеквизитТЧРезультатовДата = НачалоДня(ВыборкаДетальныеЗаписи.Дата);
					Если Запись.Сумма > 0 Тогда
						СтрокаДобавления.РеквизитТЧРезультатовСуммаБН = Запись.Сумма;
						СтрокаДобавления.РеквизитТЧРезультатовСуммаБНВозвр = 0;
					Иначе
						СтрокаДобавления.РеквизитТЧРезультатовСуммаБН = 0;
						СтрокаДобавления.РеквизитТЧРезультатовСуммаБНВозвр = (-1)*Запись.Сумма;
					КонецЕсли;
				ИначеЕсли Запись.СубконтоКт.Контрагенты = РеквизитБезНал и Запись.СубконтоКт.Договоры = РеквизитДоговор Тогда
					СтрокаДобавления = ТабличнаяЧастьРезультатов.Добавить();
					СтрокаДобавления.РеквизитТЧРезультатовДата = НачалоДня(ВыборкаДетальныеЗаписи.Дата);
					Если Запись.Сумма > 0 Тогда
						СтрокаДобавления.РеквизитТЧРезультатовСуммаБН = 0;
						СтрокаДобавления.РеквизитТЧРезультатовСуммаБНВозвр = Запись.Сумма;
					Иначе
						СтрокаДобавления.РеквизитТЧРезультатовСуммаБН = (-1)*Запись.Сумма;
						СтрокаДобавления.РеквизитТЧРезультатовСуммаБНВозвр = 0;
					КонецЕсли;
				КонецЕсли;
			КонецЦикла;
		КонецЕсли;
	КонецЦикла;
	НаборЗаписей.Очистить();
[/spoil]
Время выполнения запроса не зависит от доступной роли и составляет ту же 1 секунду.
13.06.2013 13:25
izuware
 
Цитата:
KirillHome ...
Выход - не обращаться к регистру ХозрасчетныйДвиженияССубконто через запрос, а выбирать данные через "НаборЗаписей"
как нашел ?
13.06.2013 14:40
KirillHome
 
Цитата:
izuware как нашел ?
Как нашёл проблему?
Писал обработку под пользователем с полными правами, с ним же и проверял. Всё хорошо, правильно, быстро. Ну, думаю, надо ставить, показывать.

Показываю пользователю - а у него "тормозит".
Запускаю под собой - всё опять быстро.
Стал разбираться, смотреть - "на чём затык", опытным путём понял, что проблема - в обращении с пользовательскими правами к данному регистру (похоже, не отрабатывает отбор по регистратору).

Как нашёл решение?
Поискал в гугле, увидел где-то слова о том, что данный регистр - "медленный", и рекомендацию использовать "НаборЗаписей".
Дальше - всё просто :)
15.06.2013 00:37
KirillHome
 
Продолжаю изыскания :)

Понял, откуда "растут ноги" тормоза при обращении к данному регистру: ХозрасчетныйДвиженияССубконто
Это следствие т.н. RLS (Record Level Security) - ограничения прав доступа пользователей на уровне записей.
Собственно, тормозит именно данный механизм - если снимаем в конфигураторе ограничения по чтению данного регистра для роли "Бухгалтер" - то всё работает быстро.

Недостаток решения через "НаборЗаписей" - данный вариант не работает в режиме "Толстый клиент (управляемое приложение)" по причине недоступности в этом режиме функции ГлобальногоМодуля "глЗначениеПеременной" (во всех остальных - работает).
Ошибка возникает при вызове:
Код:
РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
При этом нет никакой разницы, где это вызывать - &НаКлиенте или &НаСервере.

Вариант выхода - использовать проверку
Код:
	# Если ТолстыйКлиентУправляемоеПриложение Тогда
		//Получаем данные через запрос по РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто
	#Иначе
		//Получаем данные через НаборЗаписей
	# КонецЕсли
Ещё одна возможность (которая мне, честно говоря, не нравится - нужно вносить изменения в конфигурацию, что всегда, как минимум, не очень удобно обновлять) - это поменять в ГлобальномМодуле проверку с
Код:
#Если НЕ Клиент И НЕ ВнешнееСоединение Тогда
на
Код:
#Если ТолстыйКлиентУправляемоеПриложение ИЛИ (НЕ Клиент И НЕ ВнешнееСоединение) Тогда
перед вызовом функции глЗначениеПеременной
16.06.2013 11:16
KirillHome
 
Сам ошибся, надо обращаться к регистру РегистрыБухгалтерии.Хозрасчетный не через метод СоздатьНаборЗаписей(), а через метод ВыбратьПоРегистратору(Регистратор.Ссылка) - я же не хотел записывать движения, а хотел их прочитать!

[spoil=Правильный текст запроса]
Код:
	ЗапросРучныеОперации = Новый Запрос;
	ЗапросРучныеОперации.Текст = 
	"ВЫБРАТЬ
	|	ОперацияБух.Ссылка КАК Ссылка,
	|	ОперацияБух.Дата КАК Дата
	|ИЗ
	|	Документ.ОперацияБух КАК ОперацияБух
	|ГДЕ
	|	ОперацияБух.Дата >= &ДатаНачала
	|	И ОперацияБух.Дата <= &ДатаЗавершения
	|	И ОперацияБух.ПометкаУдаления = &ПометкаУдаления
	|	И ОперацияБух.Организация = &Организация
	|";
	
	ЗапросРучныеОперации.УстановитьПараметр("ДатаНачала", НачалоДня(Объект.РеквизитДатаНачала));
	ЗапросРучныеОперации.УстановитьПараметр("ДатаЗавершения", КонецДня(Объект.РеквизитДатаЗавершения));
	ЗапросРучныеОперации.УстановитьПараметр("Организация", Объект.РеквизитОрганизация);
	ЗапросРучныеОперации.УстановитьПараметр("ПометкаУдаления", Ложь);
	
	Результат = ЗапросРучныеОперации.Выполнить();
	ВыборкаДетальныеЗаписи = Результат.Выбрать();
	
	Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
		ДвиженияБУ = РегистрыБухгалтерии.Хозрасчетный.ВыбратьПоРегистратору(ВыборкаДетальныеЗаписи.Ссылка);
		Пока ДвиженияБУ.Следующий() Цикл
			Если ДвиженияБУ.СубконтоДт.Контрагенты = Объект.РеквизитБезНал Тогда
				Если ДвиженияБУ.СубконтоДт.Договоры = Объект.РеквизитДоговор Тогда
					СтрокаДобавления = Объект.ТабличнаяЧастьРезультатов.Добавить();
					СтрокаДобавления.РеквизитТЧРезультатовДата = НачалоДня(ВыборкаДетальныеЗаписи.Дата);
					Если ДвиженияБУ.Сумма > 0 Тогда
						СтрокаДобавления.РеквизитТЧРезультатовСуммаБН = ДвиженияБУ.Сумма;
						СтрокаДобавления.РеквизитТЧРезультатовСуммаБНВозвр = 0;
					Иначе
						СтрокаДобавления.РеквизитТЧРезультатовСуммаБН = 0;
						СтрокаДобавления.РеквизитТЧРезультатовСуммаБНВозвр = (-1)*ДвиженияБУ.Сумма;
					КонецЕсли;
				ИначеЕсли ДвиженияБУ.СубконтоКт.Договоры = Объект.РеквизитДоговор Тогда
					СтрокаДобавления = Объект.ТабличнаяЧастьРезультатов.Добавить();
					СтрокаДобавления.РеквизитТЧРезультатовДата = НачалоДня(ВыборкаДетальныеЗаписи.Дата);
					Если ДвиженияБУ.Сумма > 0 Тогда
						СтрокаДобавления.РеквизитТЧРезультатовСуммаБН = 0;
						СтрокаДобавления.РеквизитТЧРезультатовСуммаБНВозвр = ДвиженияБУ.Сумма;
					Иначе
						СтрокаДобавления.РеквизитТЧРезультатовСуммаБН = (-1)*ДвиженияБУ.Сумма;
						СтрокаДобавления.РеквизитТЧРезультатовСуммаБНВозвр = 0;
					КонецЕсли;
				КонецЕсли;
			КонецЕсли;
		КонецЦикла;
	КонецЦикла;
[/spoil]

В этом случае всё правильно и быстро отрабатывает во всех режимах запуска 1с.
09.10.2014 10:10
aldemko
 
Вот у меня такая же проблема.
1с 8 с копейками. (я не спец в 1с, только выгрузку на сайт делаю, знаю только что клиент толстый (хотя для себя разницы не понимаю) и система файловая)
я в принципе нею не занимаюсь у нас есть программист 1с, передам ему.
ну а пока он в отпуске, я установлю SSD - как думаете скорость обработки увеличится (у пользователей а не админов)?
09.10.2014 10:23
KirillHome
 
Цитата:
aldemko ...как думаете скорость обработки увеличится (у пользователей а не админов)?
Не знаю, но не уверен, что скорость существенно изменится, если проблема в RLS - думаю, что в этом случае блокировки возникают на уровне 1с, а не на уровне HDD.
09.10.2014 10:38
aldemko
 
Я не особо разбираюсь в структуре и архитектуре 1с.
я для себя понял следующее.
есть файл, в котором лежат логины и права к ним.
1с, если видя что юзер не админ, начинает постоянно при каждом запросе этот файл мусолить, и интересоваться конкретно этим пользователем есть ли права, и так по списку.
(сам файл как я понял не маленький), и тут я предположил, если увеличить скорость чтения записи диска, то этот процесс, ну проверки и так далее по идее должен уменьшится.
Хотя бы на 20-30% (исходя из статей которые я читал про SSD и 1с)
будет жаль если я для себя понял не правильно
09.10.2014 10:47
KirillHome
 
Читать

Похоже, эксперимент уже ставили

Цитата:
Ситауция следующая:
Есть сотрудник А, у которого при формировании докумнта тормозит подбор номенклатуры.
Рядом сидит другой сотрудник (Б), у него права "Администратор" и "Все права", и у него ничего не тормозит.
- оба сотрудника подключаются на сервер через RDP и работают на сервере.
Сервер C2Q6600/4GB/250gb/...



Эксперимент такой:
принёс в качестве сервера Xeon X5550/24GB/40+60+128gb - SSD-диски...
64-х битный Windows,
1CПредприятие 8.2 платформа 8.2.17.169, Конфигурация "Управление торговлей" редакция 1.0 (11.0.9.15)
Скопировал базу со старого сервера, создал аналогичных пользователей (в Windows), они подключились и ситуация повторилась. Т.е. увеличение памяти и мощьности CPU правтически никак не отразилось.
Тогда мы дали пользователю A права аналогичные сотруднику Б (галки "Администратор" и "все права") и у сотрудника А всё тоже стало работать очень быстро!
Понятно что дело не в Windows, и не в мощьности сервера, а в архитектуре БД или в кривых запросах.
09.10.2014 10:55
aldemko
 
Я этот пост тоже читал.
И я заметил несколько вещей. 1 статья создана в феврале 13 года.
Эксперимент мог проводится еще ранее
То-есть те SSD возможно сами по себе могли не на много превосходить HDD (ну как предположение)
Плюс в отчете он указал что мощности CPU и оперативки никак не повлияло. про SSD ничего (почему то он на CPU И на ОЗУ внимание акцентировал а на SSD нет, хотя пишет что железо с SSD, но я бы акцентировал внимание что SSD не дал больше скорости работы с файлами).
В общем я с точностью смогу сказать только завтра.
Помогло или нет.

Здесь я уже опубликовал скриншот замеров HDD при средней нагрузке 1ски

завтра установлю SSD и выложу замеры с примерно такой же нагрузкой но на SSD, а самое главное, даст ли увеличение скорости записи чтения БД 1ски результат для частичного решения проблемы "отчёт + права пользователя"
Часовой пояс GMT +3, время: 17:27.

Форум на базе vBulletin®
Copyright © Jelsoft Enterprises Ltd.
В случае заимствования информации гипертекстовая индексируемая ссылка на Форум обязательна.