Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Обычная тема Создание временной таблицы на сервере БД (число прочтений - 3823 )
lustin
1c++ power user
Отсутствует


1C *.*, ROR, Java - на
этом остановимся

Сообщений: 907
Местоположение: Москва
Зарегистрирован: 20. Октября 2006
Пол: Мужской
Создание временной таблицы на сервере БД
31. Марта 2011 :: 08:17
Печать  
Не могу побороть поведение платформы в части создания временной таблицы на основе внешнего источника

1С делает вставку значений построчно (и 8.1.15 и 8.2.13.205)
на партнерском форуме где-то видел что платформа делает вставку массово (чего и хочу добиться)

более подробно:

1. имеем обработку ПроизвольныйКод82 (с трассировкой  SQL запросов): приложена к данному посту (мопед почти не мой - я просто совместил 2 обработки с Инфостарта: ПроизвольныйКод и КонсольЗапросовСТрассировкой)

2а. читаю в документации
Цитата:
Для того чтобы создать временную таблицу на основании внешнего источника, следует в тексте запроса в списке источников указать имя параметра, в который будет помещен внешний источник. Остальной синтаксис идентичен обычному созданию временной таблицы. В качестве внешнего источника могут выступать:
таблица значений;
табличная часть;
результат запроса.
Код
Выбрать все
 



2б. выполняю в консоли кода следующий фрагмент:

Код
Выбрать все
КС = Новый КвалификаторыСтроки(15);
	Массив = Новый Массив;
	Массив.Добавить(Тип("Строка"));
	ОписаниеТиповС = Новый ОписаниеТипов(Массив, , КС);

	тз = Новый ТаблицаЗначений;
	тз.Колонки.Добавить("Тесть",ОписаниеТиповС);

	Для сч = 1 По 128 Цикл
		тз.Добавить().Тесть = "Тесть"+сч;
	КонецЦикла;

	_запрос = Новый Запрос;
	_запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;

	_запрос.Текст = "ВЫБРАТЬ Тесть ПОМЕСТИТЬ втХрень ИЗ &тз КАК Хрень ; выбрать * из втХрень; УНИЧТОЖИТЬ втХрень";

	_запрос.УстановитьПараметр("тз",тз);

	Попытка
		результат = _запрос.Выполнить();
	Исключение
		ВызватьИсключение ОписаниеОшибки();
	КонецПопытки;

	_запрос.Текст = "ВЫБРАТЬ Тесть ПОМЕСТИТЬ втХрень ИЗ &результат КАК Хрень; ВЫБРАТЬ * ИЗ втХрень; УНИЧТОЖИТЬ втХрень";
	_запрос.УстановитьПараметр("результат",результат);

	Попытка
		результат = _запрос.Выполнить();
	Исключение
		ВызватьИсключение ОписаниеОшибки();
	КонецПопытки;
 



3. вижу результат трассировки и понимаю что 1С-сина в своих внутренностях выполняет примерно следующую инструкцию:
Код
Выбрать все
for each value from VT do
   execSQL("N'INSERT INTO %temp (%field) VALUES(@P1)',N'@P1 %typev ',N'%value'", value)
end do
 


в итоге я вижу 128 вызовов типа "INSERT".


Внимание вопрос: умеет ли восьмерка (хоть какая нибудь) делать массовую вставку во временую таблицу.

P.S. Если кому интересно почему именно 128 - могу отдельно рассказать:
мне эта Времянка нужна потом для фильтров и если Времянка будет из одной колонки
то прекрасно работает конструкция "ГДЕ ЧетоТам В($параметрСписокЗначений)"
однако есть 2 проблемы
1. если Список будет иметь более 128 значений - тогда он уедет на SQL как временная таблица все равно: по принципу такому же как код выше.
2. если в запросе будет фильтрация вида "ГДЕ Номенклатура.Ссылка В(&СписокСсылок) И Номенклатура.ЭтоГруппа"
и в СпискеСсылок будет значений более чем 1000 (эмпирическим путем выявлено) Оптимизатор SQL построит слегка Невеселый пан запроса с секцией MissingIndex  Озадачен

P.S.S. Один выход я уже нашел  Улыбка вызывать Запрос со СпискамиСсылок нарезанными по 128 значений, а потом в коде объединять таблицы результатов - работает быстрее и Оптимизатор не нагибается.

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

_______________82.zip ( 125 KB | Загрузки )

бизнес-процесс как техническое задание прекрасно, только у бизнеса нет процессов; у бизнеса есть желание выжить
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
trad
1c++ power user
1c++ donor
1c++ moderator
Отсутствует



Сообщений: 3046
Местоположение: Киров
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: Создание временной таблицы на сервере БД
Ответ #1 - 31. Марта 2011 :: 08:56
Печать  
если говорить о ms sql, то я например знаю только 3 инсерта:
insert ... values - вставка одной строки
insert ... select - вставка нескольких строк, но тут не подходит
bulk insert - вставка из файла, тоже не подходит

Цитата:
Внимание вопрос: умеет ли восьмерка (хоть какая нибудь) делать массовую вставку во временую таблицу.

вопрос то наверно не к восьмерке, а к субд
  

1&&2&&3
Наверх
 
IP записан
 
lustin
1c++ power user
Отсутствует


1C *.*, ROR, Java - на
этом остановимся

Сообщений: 907
Местоположение: Москва
Зарегистрирован: 20. Октября 2006
Пол: Мужской
Re: Создание временной таблицы на сервере БД
Ответ #2 - 31. Марта 2011 :: 09:31
Печать  
trad писал(а) 31. Марта 2011 :: 08:56:
если говорить о ms sql, то я например знаю только 3 инсерта:
insert ... values - вставка одной строки
insert ... select - вставка нескольких строк, но тут не подходит
bulk insert - вставка из файла, тоже не подходит

Цитата:
Внимание вопрос: умеет ли восьмерка (хоть какая нибудь) делать массовую вставку во временую таблицу.

вопрос то наверно не к восьмерке, а к субд


Спасибо, чувствую ты прав.
Я почему то не дошел в исследованиях до вопроса "А может ли это СУБД"  Смущённый

Придется использовать запрос с порциями по 128 значений в качестве фильтра.

P.S. Консольку берите кому нужно Подмигивание, классная вещь.
  

бизнес-процесс как техническое задание прекрасно, только у бизнеса нет процессов; у бизнеса есть желание выжить
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Создание временной таблицы на сервере БД
Ответ #3 - 31. Марта 2011 :: 10:33
Печать  
trad писал(а) 31. Марта 2011 :: 08:56:
если говорить о ms sql, то я например знаю только 3 инсерта:
insert ... values - вставка одной строки
insert ... select - вставка нескольких строк, но тут не подходит
bulk insert - вставка из файла, тоже не подходит

Цитата:
Внимание вопрос: умеет ли восьмерка (хоть какая нибудь) делать массовую вставку во временую таблицу.

вопрос то наверно не к восьмерке, а к субд

в sql2008  появился способ одним insert вставить
в таблицу сразу несколько строк.
  
Наверх
 
IP записан
 
lustin
1c++ power user
Отсутствует


1C *.*, ROR, Java - на
этом остановимся

Сообщений: 907
Местоположение: Москва
Зарегистрирован: 20. Октября 2006
Пол: Мужской
Re: Создание временной таблицы на сервере БД
Ответ #4 - 31. Марта 2011 :: 12:09
Печать  
Z1 писал(а) 31. Марта 2011 :: 10:33:
trad писал(а) 31. Марта 2011 :: 08:56:
если говорить о ms sql, то я например знаю только 3 инсерта:
insert ... values - вставка одной строки
insert ... select - вставка нескольких строк, но тут не подходит
bulk insert - вставка из файла, тоже не подходит

Цитата:
Внимание вопрос: умеет ли восьмерка (хоть какая нибудь) делать массовую вставку во временую таблицу.

вопрос то наверно не к восьмерке, а к субд

в sql2008  появился способ одним insert вставить
в таблицу сразу несколько строк.


хм, а вот это интересно.

я пошел к Гуглу и обнаружил
http://blog.sqlauthority.com/2008/07/02/sql-server-2008-insert-multiple-records-...

если немного порадоваться за тех кто работает с SQL 2008 напрямую, а потом посмотреть на статью по ссылке, то возникает вопрос на исследование:

А что будет быстрее с точки зрения 1С ?

код типа:
Код
Выбрать все
_запрос = Новый Запрос;
...
КонецЦикла;
_запрос.Текст = "ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура ГДЕ ссылка В(&СписокПараметров)"
...
_запрос.Выполнить();
 



или

Код
Выбрать все
_запрос = Новый Запрос;
_запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;

сз = Новый СписокЗначений;
Для сч = 1 По 129 Цикл
	сз.Добавить("Тесть"+сч);
КонецЦикла;

	текстЗапросСозданияВТ = "ВЫБРАТЬ Параметр ПОМЕСТИТЬ втПараметров ИЗ (";
	Для сч = 0 по сз.Количество()-1 Цикл
		ИмяПараметра = "Параметр"+Формат(сч,"ЧГ=0");
		текстЗапросСозданияВТ = текстЗапросСозданияВТ + ?(сч = 0, Символы.ПС, " ОБЪЕДИНИТЬ ВСЕ " + Символы.ПС) + "ВЫБРАТЬ &"+ИмяПараметра + " КАК Параметр";
		_запрос.УстановитьПараметр(ИмяПараметра,сз[сч]);
	КонецЦикла;
	текстЗапросСозданияВТ = текстЗапросСозданияВТ + " ) как ХитраяВременнаяТаблица";
	_запрос.Выполнить();
 



пошел экспериментировать
  

бизнес-процесс как техническое задание прекрасно, только у бизнеса нет процессов; у бизнеса есть желание выжить
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
lustin
1c++ power user
Отсутствует


1C *.*, ROR, Java - на
этом остановимся

Сообщений: 907
Местоположение: Москва
Зарегистрирован: 20. Октября 2006
Пол: Мужской
Re: Создание временной таблицы на сервере БД
Ответ #5 - 31. Марта 2011 :: 12:45
Печать  
lustin писал(а) 31. Марта 2011 :: 12:09:
пошел экспериментировать


ну вообщем итоговый запрос на создание временной таблицы

Код
Выбрать все
_запрос = Новый Запрос;
_запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;

сз = Новый СписокЗначений;
Для сч = 1 По 129 Цикл
	сз.Добавить("Тесть"+сч);
КонецЦикла;

текстЗапросСозданияВТ = "ВЫБРАТЬ Параметр ПОМЕСТИТЬ втПараметров ИЗ (";
Для сч = 0 по сз.Количество()-1 Цикл
	ИмяПараметра = "ХитрыйПараметр"+Формат(сч,"ЧГ=0");
	текстЗапросСозданияВТ = текстЗапросСозданияВТ + ?(сч = 0, Символы.ПС, Символы.ПС + " ОБЪЕДИНИТЬ ВСЕ " + Символы.ПС) + "ВЫБРАТЬ &"+ИмяПараметра + " КАК Параметр";

	_запрос.УстановитьПараметр(ИмяПараметра,сз.Получить(сч).Значение);
КонецЦикла;

текстЗапросСозданияВТ = текстЗапросСозданияВТ + " ) как ХитраяВременнаяТаблица ИНДЕКСИРОВАТЬ ПО Параметр";
_запрос.Текст = текстЗапросСозданияВТ;
Попытка
	_запрос.Выполнить();
Исключение
	Сообщить(_запрос.Текст);
	ВызватьИсключение ОписаниеОшибки();
КонецПопытки;

 



получается запрос типа

Цитата:
ВЫБРАТЬ * ПОМЕСТИТЬ втХрень ИЗ (
ВЫБРАТЬ &ХитрыйПараметр1
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ &ХитрыйПараметр2
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ &ХитрыйПараметр3
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ &ХитрыйПараметр4
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ &ХитрыйПараметр5
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ &ХитрыйПараметр6
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ &ХитрыйПараметр7
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ &ХитрыйПараметр8
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ &ХитрыйПараметр9
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ &ХитрыйПараметр10
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ &ХитрыйПараметр11
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ &ХитрыйПараметр12
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ &ХитрыйПараметр13
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ &ХитрыйПараметр14
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ &ХитрыйПараметр15
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ &ХитрыйПараметр16
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ &ХитрыйПараметр17
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ &ХитрыйПараметр18
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ &ХитрыйПараметр19
ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ &ХитрыйПараметр20 ) как ХитраяВременнаяТаблица ИНДЕКСИРОВАТЬ ПО Параметр
;


уфффф, и оно работает веселее вроде.
  

бизнес-процесс как техническое задание прекрасно, только у бизнеса нет процессов; у бизнеса есть желание выжить
Наверх
GTalkSkype/VoIPICQ  
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать