|
Мои запросы в цикле тормозят и делают не то, что нужно, что мне делать | ☑ | ||
---|---|---|---|---|
0
breezee
07.07.15
✎
21:07
|
Очень большая база, нужно вытянуть много данных, записать в excel, в общем все виснет к чертям и не собирается завершаться. Может можно как-то
1) в самом запросе разбивать строковео значение на массив подстрок 2) в самом запросе сделать вложенный цикл, как для таблицу значений, ни чего просчитывать там не надо, надо только вывести все возможные сочетания из массива, полученного из строки |
|||
1
Волшебник
модератор
07.07.15
✎
21:10
|
зачем в Excel?
|
|||
2
Волшебник
модератор
07.07.15
✎
21:11
|
Excel предназначен для анализа человеком, а не для учёта первички. Человек не может проанализировать много. Значит нужно вытягивать уже сводные данные
|
|||
3
ДенисЧ
07.07.15
✎
21:11
|
Вон из профессии
|
|||
4
Garykom
гуру
07.07.15
✎
21:12
|
не надо прайсы в ексель а? ну не надо....
|
|||
5
breezee
07.07.15
✎
21:12
|
(1) Там обработка написанная для загрузки в другую базу, мне сказали доделывать, срочно, я в 1с еще не спец
|
|||
6
Волшебник
модератор
07.07.15
✎
21:13
|
(5) учи матчасть
|
|||
7
Волшебник
модератор
07.07.15
✎
21:13
|
выгрузка-загрузка из базы в базу делается через XML или COM-соединение
|
|||
8
breezee
07.07.15
✎
21:20
|
(7) Я это понимаю, но раз сделали так - значит удобнее. Не в этом суть, я сам сейчас в любом случае не смогу написать полноценный обмен и т.д. Мне нужно сделать следующее - есть свойство размерный ряд у номенклатуры, на пример 42-26, есть характериситки(на пример красный, зеленый) - нужно составить все сочитания для номеналатуры, + для той у которой нет свойство выписать с характериситками и для той у которой нет характеристик - выпсиать со свойствами. Я все сделал через запросы и потом выгружал их в тз, с тз и работал. Все грузилось минут 20, но грузилось, потом сказали добавить цены последние - я сделал это запросом для каждой номенклатуры, - все стало совсем долго, 1с хоть и не вылетает, но когда нажимаю alt+tab в списке только иконка конфигуратора, а предприятия нет. Через конфигрутаор захожу - нарисованы часы, показывает что идет загрузка.
|
|||
9
Волшебник
модератор
07.07.15
✎
21:21
|
(8) запросы в цикле - это зло
|
|||
10
Garykom
гуру
07.07.15
✎
21:22
|
(9) не, это не всегда зло
вот когда не специалисты берутся делать то что не умеют это да зло |
|||
11
breezee
07.07.15
✎
21:26
|
(9) А если я выгружу полученное в тиблицу значений и буду в циле сравнивать - будет оптимальнее?
|
|||
12
Волшебник
модератор
07.07.15
✎
21:28
|
(11) Сделай замер производительности и доложи
|
|||
13
breezee
07.07.15
✎
22:39
|
Не помогает ничего, там 20 тысяч строк получается. ЧТо делать? Можно это как-то по часям разбить?
|
|||
14
Лефмихалыч
07.07.15
✎
22:42
|
(13) ссаных 20 тысяч - это курям на смех
|
|||
15
breezee
07.07.15
✎
22:45
|
(14) Там 4 вложенных цикла. Может я скину этот шизфореничный бред сюда и Вы поможете разбраться?
|
|||
16
breezee
07.07.15
✎
22:46
|
Прошу прощение за внешний вид. Сказали завтра сдавать, делал в спешке
Процедура КнопкаВыполнитьНажатие(Кнопка) Режим = РежимДиалогаВыбораФайла.Сохранение; ДиалогВыбора = новый ДиалогВыбораФайла(Режим); ДиалогВыбора.ПолноеИмяФайла = ""; Фильтр = "Файл данных (*.xls)|*.xls"; ДиалогВыбора.Фильтр = Фильтр; ДиалогВыбора.Заголовок = "Выберите Каталог"; Если ДиалогВыбора.Выбрать() Тогда ТабДок = СформироватьТабДок(); ТабДок.Записать(ДиалогВыбора.ПолноеИмяФайла,ТипФайлаТабличногоДокумента.XLS97); Сообщить("Успешно!"); Иначе Сообщить("Файл не сохранен!"); КонецЕсли; КонецПроцедуры Функция РазложитьСтрокуВМассивПодстрок(Знач Строка, Знач Разделитель = ",", Знач ПропускатьПустыеСтроки = Неопределено) Результат = Новый Массив; // для обеспечения обратной совместимости Если ПропускатьПустыеСтроки = Неопределено Тогда ПропускатьПустыеСтроки = ?(Разделитель = " ", Истина, Ложь); Если ПустаяСтрока(Строка) Тогда Если Разделитель = " " Тогда Результат.Добавить(""); КонецЕсли; Возврат Результат; КонецЕсли; КонецЕсли; // Позиция = Найти(Строка, Разделитель); Пока Позиция > 0 Цикл Подстрока = Лев(Строка, Позиция - 1); Если Не ПропускатьПустыеСтроки Или Не ПустаяСтрока(Подстрока) Тогда Результат.Добавить(Подстрока); КонецЕсли; Строка = Сред(Строка, Позиция + СтрДлина(Разделитель)); Позиция = Найти(Строка, Разделитель); КонецЦикла; Если Не ПропускатьПустыеСтроки Или Не ПустаяСтрока(Строка) Тогда Результат.Добавить(Строка); КонецЕсли; Возврат Результат; КонецФункции Функция ПолучитьПолныйМассивРазмеров(МассивРазмеров) ПолныйМассивРазмеров = новый Массив; ПервыйЭлемент =Число(МассивРазмеров[0]); ПоследнийЭлемент =Число(МассивРазмеров[МассивРазмеров.Количество() - 1]); Пока ПервыйЭлемент <= ПоследнийЭлемент цикл ПолныйМассивРазмеров.Добавить(ПервыйЭлемент); ПервыйЭлемент = ПервыйЭлемент + 2; КонецЦикла; Возврат ПолныйМассивРазмеров; КонецФункции Функция СформироватьТабДок() цены = ВернутьЦену(); Тз = новый ТаблицаЗначений; ТЗ.Колонки.Добавить("КодНоменклатуры" , Новый ОписаниеТипов("Строка")); ТЗ.Колонки.Добавить("НаименованиеНоменклатуры" , Новый ОписаниеТипов("Строка")); ТЗ.Колонки.Добавить("Размер" , Новый ОписаниеТипов("Строка")); ТЗ.Колонки.Добавить("Цвет" , Новый ОписаниеТипов("Строка")); Тз.Колонки.Добавить("Цена", Новый ОписаниеТипов("Число")); //Тз.Колонки.Добавить("ВестиУчет", Новый ОписаниеТипов("Булево")); МассивРазмеров = новый Массив; Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ЗначенияСвойствОбъектов.Объект, | ЗначенияСвойствОбъектов.Свойство, | ЗначенияСвойствОбъектов.Значение |ИЗ | РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов"; РезультатЗапроса = Запрос.Выполнить().Выгрузить(); Для Каждого ТТ из РезультатЗапроса Цикл Если тт.Свойство.Код="000000006" И тт.Объект.ВестиУчетПоХарактеристикам И тт.Объект.ПометкаУдаления = ложь тогда //Свойство РазмерныйРяд ЕстьЦвета = Ложь; Номенклатура=тт.Объект;//Номенклатура для этого свойство РАзмерныйРяд=тт.Значение; //РазмерныйРяд само свойство //цикл по где узнаем все свойства для номенклатуры Для каждого Свойство из РезультатЗапроса цикл Если ТипЗнч(Свойство.Объект) = Тип("СправочникСсылка.ХарактеристикиНоменклатуры") тогда Если Свойство.Объект.Владелец = Номенклатура тогда ЕстьЦвета = Истина; Характеристика = Свойство.Объект; //Всякиие характеристики Характеристика = СтрЗаменить(Характеристика, "(", ""); Характеристика = СтрЗаменить(Характеристика, ")", ""); РАзмерныйРяд = СтрЗаменить(РАзмерныйРяд,"+", ""); МассивРазмеров = РазложитьСтрокуВМассивПодстрок(РАзмерныйРяд,"-"); ПолныйМассивРазмеров = ПолучитьПолныйМассивРазмеров(МассивРазмеров); Для каждого Элемент Из ПолныйМассивРазмеров цикл //НоваяХарактеристика = ""+Элемент + ", " + Характеристика; ТзНоваяСтрока = Тз.Добавить(); ТзНоваяСтрока.КодНоменклатуры = Номенклатура.Код; ТзНоваяСтрока.НаименованиеНоменклатуры = Номенклатура.Наименование; ТзНоваяСтрока.Размер = Элемент; ТзНоваяСтрока.Цвет = Характеристика; //ТзНоваяСтрока.цена = ВернутьЦену(Номенклатура,Свойство.Объект , тт.Объект.ВестиУчетПоХарактеристикам); Для каждого СтрЦена из цены цикл Если СтрЦена.Характеристика = Характеристика и СтрЦена.Номенклатура = Номенклатура тогда ТзНоваяСтрока.цена = СтрЦена.цена; КонецЕсли; КонецЦикла; КонецЦикла; КонецЕсли; КонецЕсли; КонецЦикла; Если НЕ ЕстьЦвета Тогда МассивРазмеров = РазложитьСтрокуВМассивПодстрок(РАзмерныйРяд,"-"); ПолныйМассивРазмеров = ПолучитьПолныйМассивРазмеров(МассивРазмеров); Для каждого Элемент Из ПолныйМассивРазмеров цикл ТзНоваяСтрока = Тз.Добавить(); ТзНоваяСтрока.КодНоменклатуры = Номенклатура.Код; ТзНоваяСтрока.НаименованиеНоменклатуры = Номенклатура.Наименование; ТзНоваяСтрока.Размер = Элемент; ТзНоваяСтрока.Цвет = ""; //ТзНоваяСтрока.ВестиУчет = тт.Объект.ВестиУчетПоХарактеристикам; //ТзНоваяСтрока.цена = ВернутьЦену(Номенклатура, , тт.Объект.ВестиУчетПоХарактеристикам); Для каждого СтрЦена из цены цикл Если СтрЦена.Номенклатура = Номенклатура тогда ТзНоваяСтрока.цена = СтрЦена.цена; КонецЕсли; КонецЦикла; КонецЦикла; КонецЕсли; КонецЕсли; КонецЦикла; //ВЫБОРКА ВСЕХ БЕЗ РАЗМЕРНОГО РЯДА Для каждого Свойство из РезультатЗапроса цикл ЕстьЦвета = Ложь; Если ТипЗнч(Свойство.Объект) = Тип("СправочникСсылка.ХарактеристикиНоменклатуры") тогда //номенклатура = свойство.объект; Номенклатура = Свойство.Объект.Владелец; Для Каждого ТТ из РезультатЗапроса Цикл Если Номенклатура = тт.объект и тт.Свойство.Код="000000006" тогда //Свойство РазмерныйРяд ЕстьЦвета = Истина; КонецЕсли; КонецЦикла; Если НЕ ЕстьЦвета Тогда ТзНоваяСтрока = Тз.Добавить(); ТзНоваяСтрока.КодНоменклатуры = Номенклатура.Код; ТзНоваяСтрока.НаименованиеНоменклатуры = Номенклатура.Наименование; ТзНоваяСтрока.Размер = ""; ТзНоваяСтрока.Цвет = Свойство.Объект; //ТзНоваяСтрока.ВестиУчет = тт.Объект.ВестиУчетПоХарактеристикам; //ТзНоваяСтрока.цена = ВернутьЦену(Номенклатура,Свойство.Объект , тт.Объект.ВестиУчетПоХарактеристикам); Для каждого СтрЦена из цены цикл Если СтрЦена.Характеристика = Свойство.Объект и СтрЦена.Номенклатура = Номенклатура тогда ТзНоваяСтрока.цена = СтрЦена.цена; КонецЕсли; КонецЦикла; КонецЕсли; КонецЕсли; КонецЦикла; //Для каждого Строка из тз цикл // Строка.Цена = ПолучитьЦену(Строка.КодНоменклатуры, Строка.Цвет, Строка.ВестиУчет); //КонецЦикла; //КОНЕЦ ВЫБОРКИ ВСЕХ БЕЗ РАЗМЕРНОГО РЯДА ТабДок = Новый ТабличныйДокумент; Построитель = Новый ПостроительОтчета; Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТЗ); Построитель.Вывести(ТабДок); ОблУдал = ТабДок.Область("R1:R3"); ТабДок.УдалитьОбласть(ОблУдал,ТипСмещенияТабличногоДокумента.ПоВертикали); Возврат ТабДок; КонецФункции Функция ВернутьЦену() Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ЦеныНоменклатурыСрезПоследних.Цена, | ЦеныНоменклатурыСрезПоследних.Номенклатура, | ЦеныНоменклатурыСрезПоследних.ХарактеристикаНоменклатуры КАК Характеристика |ИЗ | РегистрСведений.ЦеныНоменклатуры.СрезПоследних КАК ЦеныНоменклатурыСрезПоследних |ГДЕ | ЦеныНоменклатурыСрезПоследних.ТипЦен = &ТипЦен"; Запрос.УстановитьПараметр("ТипЦен", ПолеВвода1); //Запрос.УстановитьПараметр("Номенклатура", Номенклатура); РезультатЗапроса = Запрос.Выполнить(); ВыборкаДетальныеЗаписи = РезультатЗапроса.Выгрузить(); // Пока ВыборкаДетальныеЗаписи.Следующий() Цикл // цена = ВыборкаДетальныеЗаписи.цена; // КонецЦикла; //КонецЕсли; Возврат ВыборкаДетальныеЗаписи; КонецФункции |
|||
17
Garykom
гуру
07.07.15
✎
22:50
|
(16) это пипипи
|
|||
18
Лефмихалыч
07.07.15
✎
22:51
|
(15) ах*уееееть ЧЕТЫРЕ?!?!?!?!1111одинодин ААААААЯФШОКЕ
|
|||
19
breezee
07.07.15
✎
22:51
|
Так, за 30 минут собралось, нет многих цен, в самом начале. Сейчас посмотрю что не так, но все вроде собралось
|
|||
20
breezee
07.07.15
✎
22:52
|
(18) Так сильно же режет производительность. Или я что-то не понимаю?
|
|||
21
Лефмихалыч
07.07.15
✎
22:52
|
запросы в цикле - признак дурачины, кстати сказать
|
|||
22
Лефмихалыч
07.07.15
✎
22:54
|
(16) у меня для тебя плохие новости: в твоем коде нечего чинить. Его надо целиком сжечь дотла и написать заново.
|
|||
23
Garykom
гуру
07.07.15
✎
22:54
|
(21) иногда без этого ну никак (очень редко)
но в данном случае это признак генетической аномалии |
|||
24
KarpovDeniska
07.07.15
✎
22:56
|
Оптимизация алгоритмов 8.1 ......
|
|||
25
Лефмихалыч
07.07.15
✎
22:56
|
(23) нашел, кого учить...
|
|||
26
Лефмихалыч
07.07.15
✎
22:57
|
(24) починил
|
|||
27
KarpovDeniska
07.07.15
✎
23:03
|
(16) цены с отбором по номенклатуре/характеристике получай и вложенные циклы по одним и тем же данным убери. Поможет немного
|
|||
28
breezee
07.07.15
✎
23:08
|
(27) Спасибо, а как их убрать? Мне же нужен перебор по всем значениям. Я пытался и делать отдельные запросы для получения цен. А отбор по характеристке не всегда нужен, так что я выбираю все цены и потом обрщаюсь к некоторым по характеристике и номенклатуре, а к некоторым просто по номенклатуре
|
|||
29
Лефмихалыч
07.07.15
✎
23:09
|
(28) засунь всё в запрос
|
|||
30
Wern
07.07.15
✎
23:51
|
Ну нашлись куча перфекционистов. Да хоть 10 вложенных циклов, лишь бы работало. Думать надо головой, а не оптимизировать все подряд что нужно и что не нужно. Пол часа для одноразового действия, более чем нормально.
|
|||
31
hhhh
08.07.15
✎
00:12
|
(28) вот эту бредятину убери
Если тт.Свойство.Код="000000006" И тт.Объект.ВестиУчетПоХарактеристикам И тт.Объект.ПометкаУдаления = ложь тогда //Свойство РазмерныйРяд вот так будет быстрее в десятки раз "ВЫБРАТЬ | ЗначенияСвойствОбъектов.Объект, | ВЫРАЗИТЬ(ЗначенияСвойствОбъектов.Объект КАК Справочник.Номенклатура).ВестиУчетПоХарактеристикам КАК ВестиУчетПоХарактеристикам, | ВЫРАЗИТЬ(ЗначенияСвойствОбъектов.Объект КАК Справочник.Номенклатура).ПометкаУдаления КАК ПометкаУдаления, | ЗначенияСвойствОбъектов.Свойство, | ЗначенияСвойствОбъектов.Свойство.Код КАК СвойствоКод, | ЗначенияСвойствОбъектов.Значение |ИЗ | РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов"; |
|||
32
Zamestas
08.07.15
✎
00:56
|
(30) Есть две категории 1С'ников, которые решают задачи по извлечению данных из БД разными способами - одни циклами, вторые запросами, при этом первые (для примера) могут получить срез последних, а вторые получить те же данные за любой период (т.е. с НачДата По КонДата) одним запросом и использование циклов и таблицы в подобной конструкции считают признаком наличие лишней хромосомы в ДНК. Оно конечно пох, как разовую выгрузку реализовать, но варианты решения показывает, размеры тараканов в голове.
|
|||
33
Zamestas
08.07.15
✎
01:02
|
*показывают
|
|||
34
Злопчинский
08.07.15
✎
01:35
|
8-ка - это вообще один бльшой таракан. пруссак.
|
|||
35
Сниф
08.07.15
✎
03:07
|
(34)ты просто не умеешь его готовить. если бы у тебя было много денег, а у меня - много времени, я бы тебя обучил этому 8 за две недели.
|
|||
36
Повелитель
08.07.15
✎
06:25
|
(16) Жесть конечно.
Вот это: Для каждого СтрЦена из цены цикл Если СтрЦена.Номенклатура = Номенклатура тогда ТзНоваяСтрока.цена = СтрЦена.цена; КонецЕсли; КонецЦикла; Поменять на типовую, хоть и запрос в цикле, но это лучше чем по циклу по ценам бегать, ускорит этот гомнокод раз в 5 минимум: ТзНоваяСтрока.цена = УправлениеЦенообразованием.ПолучитьЦенуНоменклатуры(Номенклатура ,ХарактеристикаНоменклатуры , ТекТипЦен, НаДату, ЕдиницаИзмерения, ТекТипЦен.ВалютаЦены, 1, 1); |
|||
37
zsergey
08.07.15
✎
06:26
|
(16) жесть!
|
|||
38
Повелитель
08.07.15
✎
06:26
|
(36) И второй цикл по ценам тоже убрать или сколько их там
|
|||
39
commdt
08.07.15
✎
08:29
|
Не вникал в конкретную задачу, но вообще от циклов избавляет передача ТЗ в запрос и получение данных по левому соединению. При передаче ТЗ в запрос данные из неё нельзя выбирать непосредственно, сначала нужно создать временную таблицу.
Кроме того, в параметры виртуальной таблицы можно передать, например, массив используемых товаров для дальнейшего ускорения. Разумеется, если это возможно, все условия лучше задавать на самом нижнем уровне: во вложенных запросах, либо параметрах виртуальных таблиц. Типа того: ИсходнаяТаб = Документ.Товары.Выгрузить(); ИсходнаяТаб.Свернуть("Номенклатура,ХарактеристикаНоменклатуры"); Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ИсходнаяТаб.Номенклатура, | ИсходнаяТаб.ХарактеристикаНоменклатуры |ПОМЕСТИТЬ ТабНоменклатуры |ИЗ | &ИсходнаяТаб КАК ИсходнаяТаб |; | |//////////////////////////////////////////////////////////////////////////////// |ВЫБРАТЬ | ТабНоменклатуры.Номенклатура, | ТабНоменклатуры.ХарактеристикаНоменклатуры, | ЦеныНоменклатурыСрезПоследних.Цена, | ЦеныНоменклатурыСрезПоследних.Валюта |ИЗ | ТабНоменклатуры КАК ТабНоменклатуры | ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних( | &Дата, | ТипЦен = &ТипЦен | И Номенклатура В (&Номенклатура)) КАК ЦеныНоменклатурыСрезПоследних | ПО ТабНоменклатуры.Номенклатура = ЦеныНоменклатурыСрезПоследних.Номенклатура | И ТабНоменклатуры.ХарактеристикаНоменклатуры = ЦеныНоменклатурыСрезПоследних.ХарактеристикаНоменклатуры |; | |//////////////////////////////////////////////////////////////////////////////// |УНИЧТОЖИТЬ ТабДанных"; Запрос.УстановитьПараметр("ТипЦен", ТипЦен); Запрос.УстановитьПараметр("Дата", Дата); Запрос.УстановитьПараметр("Номенклатура", ИсходнаяТаб.ВыгрузитьКолонку("Номенклатура")); Запрос.УстановитьПараметр("ИсходнаяТаб", ИсходнаяТаб); Результат = Запрос.Выполнить().Выгрузить(); И - да, не забывайте удалять временные таблицы. |
|||
40
Лефмихалыч
08.07.15
✎
08:33
|
+(32) бело бы "пох", ветки бы не было. Метод "пох, как - одноразово, же" дает ровно вот то, что в сабже - оно тормозит и делает не то, что надо, сроки прошли, задача не решена.
|
|||
41
ХардHard
08.07.15
✎
08:40
|
(0) Не знаю было или нет. Вместо запроса в цикле можно формировать текст запроса в цикле , это более лучший результат часто дает. Иногда крашит все к чертям %).
По-любому с умом надо подходить к этому. |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |