Имя: Пароль:
1C
1C 7.7
v7: 7.7 + SQL работает в разы медленнее, чем 7.7 файловая. Как настроить SQL?
0 Vladal
 
30.07.12
11:57
Есть база с номенклатурой 120'000+ элементов.
К нему добавил подчиненый справочник, который надо заполнить.

Вот здесь начались фокусы. На рабочей базе, SQL 2008, этот спраовчник в монопольном режиме на выходных за 11 часов заполнился чуть меньше половины, 55000+ элементов.

Запустил эту обработку на файловой копии базы, разумеется, тоже монопольно, и за 20 минут прошел почти 20000 элементов товаров.

Интересно, как можно ускорить SQL, или это особенность и данность движка 7.7? (7.70.027)
1 Андрей_Андреич
 
naïve
30.07.12
12:00
С какой периодичностью планируется заполнять справочник? :)
2 Hipernate
 
30.07.12
12:02
Можно, было такое, придется патчить 1С ехе-ник... поищи в инете..
3 alkov
 
30.07.12
12:04
Заполнение выполняется в транзакции?
4 Vladal
 
30.07.12
12:05
Это одноразовая работа, т.к. цены хранятся в (!!!) регистре.
А чтобы по ОЛЕ не тягать временный расчет регистра. отбирать его движения. читать документ (как накодено в данной конфигурации 7.7), я и решил один раз потерять день, и потом читать справочник, заполненный на определенную дату.

Копрокод в студии:

   СпрТипыЦен = СоздатьОбъект("Справочник.ТипыЦен");
   СпрЦены = СоздатьОбъект("Справочник.Цены");
   СпрНом = СоздатьОбъект("Справочник.Товары");
   Сч = 0;
   НачатьТранзакцию();
   СпрНом.ВыбратьЭлементы();
   Пока СпрНом.ПолучитьЭлемент() = 1 Цикл
       Сч = Сч + 1;
       Если Сч%100=0 Тогда
           ЗафиксироватьТранзакцию();
           РассчитатьВремяОкончания();
           НачатьТранзакцию();
       КонецЕсли;
       Если СпрНом.ЭтоГруппа()=1 Тогда
           Продолжить;
       КонецЕсли;
       СпрЦены.ИспользоватьВладельца(СпрНом.ТекущийЭлемент());
       СпрТипыЦен.ВыбратьЭлементы();
       Пока СпрТипыЦен.ПолучитьЭлемент() = 1 Цикл
           Состояние(ТекстСообщения + " " + Сч + " " + СпрНом.ПолноеНаименование() + " / " + СпрТипыЦен);
           Если СпрЦены.НайтиПоКоду(СпрТипыЦен.Код)=1 Тогда
               //Продолжить;
           Иначе
               СпрЦены.Новый();
               СпрЦены.Код = СпрТипыЦен.Код;
               СпрЦены.Наименование = СпрТипыЦен.Наименование;
               СпрЦены.Владелец = СпрНом.ТекущийЭлемент();
           КонецЕсли;
           СЗЦен = глПрочитатьЦену(СпрНом, СпрТипыЦен, Дата(2012, 06, 30));
           Цена = СЗЦен.ПолучитьЗначение(1);
           Скидка = СЗЦен.ПолучитьЗначение(2);
           ЦСкидка = СЗЦен.ПолучитьЗначение(3);
           СпрЦены.ТипЦены = СпрТипыЦен.ТекущийЭлемент();
           СпрЦены.КодТипаЦены = СпрТипыЦен.Код;
           СпрЦены.Цена = СЗЦен.ПолучитьЗначение(1);
           СпрЦены.Скидка = СЗЦен.ПолучитьЗначение(2);
           СпрЦены.ЦСкидка = СЗЦен.ПолучитьЗначение(3);
           СпрЦены.Записать();
       КонецЦикла;
   КонецЦикла;
КонецПроцедуры
5 Vladal
 
30.07.12
12:05
(3) Да, по 100-1000+ элементов. Не у каждого товара есть цена, хотя в последней редак4ции решил писать нулевую цену также. Так что около 2000 элементов в транзакции.
6 Vladal
 
30.07.12
12:08
Вот функция чтения цены:

Функция глПрочитатьЦену(Тов,val Тип,ДатаДок="") Экспорт Тип=Число(Тип);    Рег = CreateObject("Регистр.Цены"); Рег.SetFilterValue("Товар",Тов, 1); Рег.SetFilterValue("Тип",Тип, 2); СЗ=CreateObject("ValueList");
If ДатаДок="" Then ДатаДок=ТекущаяДата();EndIf Рег.BackwardOrder(1); Рег.SelectActs(,ДатаДок);
While Рег.GetDocAct()=1 Do СЗ.AddValue(Рег.Цена);СЗ.AddValue(Рег.Скидка);СЗ.AddValue(Рег.ЦСкидка);    
Return СЗ; EndDo;
СЗ.AddValue(0);СЗ.AddValue(0);СЗ.AddValue(0); Возврат СЗ; КонецФункции
7 Salimbek
 
30.07.12
12:11
Фееричная русско-английская смесь... мой мозг сломался...
8 VladZ
 
30.07.12
12:11
(6) Круто...
Раз уж начал на одном языке - так и пиши на одном...
9 Vladal
 
30.07.12
12:11
(8) Не моё, в наследство досталось )))
Всё как в анекдоите Пятницо!
10 Vladal
 
30.07.12
12:12
Так что бы прилепить в скуль?
Это так,для развития, ибо перевожу всё с самописки на УТП.
11 akaBrr
 
30.07.12
12:13
Переделывай на прямые запросы, будет тебе счастье.
12 Vladal
 
30.07.12
12:15
(7) Она не просто русско-английская. Она еще и в_одну_строку_вся_функция
v8: Коллега-Чудотворец(маг в 1 поколении)
13 Андрей_Андреич
 
naïve
30.07.12
12:15
(11) Так человек наоборот хочет клюшки выбросить.
14 akaBrr
 
30.07.12
12:17
(13) не увидел в ветке пожеланий человека, кроме (0)
15 vde69
 
30.07.12
12:17
16 viktor_vv
 
30.07.12
12:18
А отладчик что говорит, на что больше всего времени уходит ? Мне кажись вот на это по идее, "Рег.SelectActs(,ДатаДок);". А порядок измерений в регистре какой, "Товар" там на каком месте ?
17 akaBrr
 
30.07.12
12:20
(16) ванга мод он, дольше всего у него запись делается, ванга мод офф
18 yam
 
30.07.12
12:20
Вообще сообщить явно не надо на каждом шагу выдавать, очень медленная штука
19 vde69
 
30.07.12
12:20
(15) + аналогичную по размерам загрузку удалось уложить в 15-20 минут
20 akaBrr
 
30.07.12
12:21
(19) в скул?
21 Vladal
 
30.07.12
12:21
(14) Всё правильно, интересно знать на будущее, вдруг прийдётся еще раз повторить подвиг.
22 Азат
 
30.07.12
12:21
(0) 1С++ не предлагать? там же как раз мощнейший инструментарий для работы с регистром?
23 Партизан
 
30.07.12
12:22
(4) в коде сразу видно ошибку - последняя сотня в транзакции не запишется.
24 akaBrr
 
30.07.12
12:22
(22) тут 2 проблемы, получение данных и запись
25 Андрей_Андреич
 
naïve
30.07.12
12:23
(22) Семерка умерла.
26 Партизан
 
30.07.12
12:23
прямым запросом надо
27 Азат
 
30.07.12
12:23
(25) имхо скорее сдохнут и разложатся те, кто предрекал ей скорую гибель)
28 Азат
 
30.07.12
12:24
(24) какие проблемы с получением?
29 akaBrr
 
30.07.12
12:24
(28) без 1С++ меееедлееееноооооо
30 Salimbek
 
30.07.12
12:24
Х.з. у меня такой код за 10 секунд отрабатывает
   ТекстЗапроса = "
   |SELECT $ЦеныПродажи.Товар Товар
   |    , Max(ЦеныПродажи.DATE_TIME_IDDOC) Максимум
   |INTO #tmp_Log_Cen
   |FROM $Регистр.ЦеныПродажи AS ЦеныПродажи With (NOLOCK)
   |WHERE $ЦеныПродажи.КатегорияЦен = :ВыбКатегория~
   |GROUP BY $ЦеныПродажи.Товар";
   
   глРС_Аддон.УстановитьТекстовыйПараметр("ВыбКатегория", КатегорияЦенРозницы);
   глРС_Аддон.ВыполнитьСкалярный(ТекстЗапроса);
   
   ТекстЗапроса = "
   |SELECT
   |    Спр.Code [ArticleId $Число]
   |    , $ЦеныПродажи.Цена [BasePrice $Число]
   |    , 0 [CurrencyPrice $Число]
   |FROM $Регистр.ЦеныПродажи AS ЦеныПродажи With (NOLOCK)
   |    INNER JOIN #tmp_Log_Cen t ON $ЦеныПродажи.Товар=t.Товар AND ЦеныПродажи.DATE_TIME_IDDOC=t.Максимум
   |    INNER JOIN $Справочник.Номенклатура Спр ON t.Товар=Спр.Id
   |WHERE $ЦеныПродажи.Цена<>0";
   ИТЗ = глРС_Аддон.ВыполнитьИнструкцию(ТекстЗапроса, ИТЗ_сегодня, 0);
А дальше - перебор ИТЗ с записью
31 vde69
 
30.07.12
12:24
(20) здесь дело не в скуле а в том, что идет цикл на 200 000 номенклатуры и внутри него вызывается не только запись но и ком обращения и соответсвено чтение отдельным запросом...

нужно сначало стянуть всю таблицу в семерку (правда есть шанс вылететь по памяти) и потом уже эту таблица распихивать....
32 Партизан
 
30.07.12
12:25
(27) +100
33 viktor_vv
 
30.07.12
12:25
(28) Если неудачно стоят измерения, и нет отборов, то получение движений из регистра с фильтром очень тормозить может.
34 Vladal
 
30.07.12
12:25
35 viktor_vv
 
30.07.12
12:26
(31) Так там вроде нету com-обращений.
36 Vladal
 
30.07.12
12:27
(18) Дык его и нет, того "сообщить", есть "состояние".
Вопрос в другом - на скуле за 11 часов обработано 55000+ элементов, а в файловой это же количество - за примерно за час.
37 viktor_vv
 
30.07.12
12:28
(34) Это как, фильтр по реквизитуставиться, что ли ?
38 Vladal
 
30.07.12
12:28
(23) Точно. Я не доглядел. Спасибо.
39 viktor_vv
 
30.07.12
12:28
(37)* "реквизиту ставится"
40 Vladal
 
30.07.12
12:28
(37) Да. Об этом говорит фееричный листинг.
41 Азат
 
30.07.12
12:29
(29) а не пе*дишь ли ты? по адо тож быстро отработает
42 Salimbek
 
30.07.12
12:29
(36) А ты в монопольном/однопользовательском режиме? А то попробуй в файловой, когда еще хоть один подключится к базе...
43 viktor_vv
 
30.07.12
12:30
(39)+ Так это вообще жесть, там индексы нихрена нельзя поставить на реквизит.
44 akaBrr
 
30.07.12
12:30
(41) а не пойти ли тебе, и не почитать ли ветку, или еще раз не перечитать, что я написал?
45 Vladal
 
30.07.12
12:33
(31) Я почти так и поступил. Всю таблицу стянул в подчиненный справочник, его и щаполняю, его же и буду читать в COM из 8-ки.
(35) их и не будет - пробовал из 8-ки тянуть по COM вычисление функции получения цены, доооолгоооо дело было.
46 Vladal
 
30.07.12
12:34
(42) Анакуа? Ща все работу работают, жалуются, что база тормозит. Вот я и развернул копию. Файловую.
47 opus70
 
30.07.12
12:50
если это стандартная ТИС то проще всего купить у Паула toysql потрахаться с месяцок на интеграцию и спать спокойно
или капать в сторону 1с++ (но тогда самому придется много переписывать)

т.е. смотря как поджимает время
48 Vladal
 
30.07.12
12:51
(47) Нет, это нетленка. Единственный плюс - это документ назначения цен, аналог которого есть в УТП.
49 akaBrr
 
30.07.12
12:52
(48) запись может напрямую в таблицу делать?
50 Злой Бобр
 
30.07.12
13:01
(0) А причем тут скуль? Учитывая код (4) причина в кривизне рук (кода).
200 тыс позиций это как семечки на базаре ...
51 viktor_vv
 
30.07.12
13:02
(48) Так там в принципе переписать только функцию получение цен, по идее должно быть побыстрее, чем стандартными средствами.
52 Ёпрст
 
30.07.12
13:04
(0) а нафига всей номенклатуре ВСЕ типы цен вводить ?
заняться нечем ?
53 viktor_vv
 
30.07.12
13:05
Правда в приведенном варианте все равно без индексов и скульным запросом будет не очень.
54 viktor_vv
 
30.07.12
13:07
(50) Так 200 к только номенклатуры, а сколько там записей в регистре получается.
55 Злой Бобр
 
30.07.12
13:14
(54) Да без разницы. Посмотри картинку в (34), ток смотри неупади. Нетленка зачетная. Прям как серпом по яй***.
56 Vladal
 
30.07.12
13:15
(52) Нечем.
Несколько раз прерывали в рабочей базе, каждый раз снова. Вот и сделал, чтобы писались и нулевые цены.
57 PCcomCat
 
30.07.12
13:20
(34) Вольные художники никогда не переведутся, значит не умрем с голоду!
58 Vladal
 
30.07.12
13:21
(57) Не исключено, что автор нетленки глубоко раскаялся и перестал писать такие вещи )))
59 Злой Бобр
 
30.07.12
13:29
(58) Ну ты хоть понял в чем твоя ошибка? Автор нетленки нас неинтересует.
60 Vladal
 
30.07.12
13:31
(59) нет, не понял. Подскажи.
61 viktor_vv
 
30.07.12
13:33
(55) Ну картинку я видел, прикольно.
Кстати а там хотя бы на реквизите Товар флажок отбор движений стоит, может поможет.
62 Vladal
 
30.07.12
13:37
(61) Нет, флажок чист. Этот реквизит не используется.
63 Злой Бобр
 
30.07.12
13:37
(60) Сначала запросом по регистру выбираешь данные. Дальше при обходе результата запроса пишешь в справочник. Быстрей всего прямым запросом, но можно и 1Совским попробовать.
64 viktor_vv
 
30.07.12
13:38
(62) Как это не используется, если по нему фильтр накладывается

Рег.SetFilterValue("Товар",Тов, 1);
65 viktor_vv
 
30.07.12
13:38
(63) +1. Тем более обработка разовая.
66 Vladal
 
30.07.12
13:41
(63) Хороший совет. Я сначала так и делал и получал пустой запрос. А чтобы иметь документ движения, к которому привязана цена, то и запрос надо с 01.01.01 по сегодня запускать, при этом память падает и 1С вываливается. Цена хранится не в ресурсе, а в реквизите.

(64) Не туда глянул. Да, в свойствах Товара стоит отбор движений. Я смотрел на измерение "Т"
67 Злой Бобр
 
30.07.12
13:56
(66) Ну и в чем проблема? Запрос в цикле с условиями или запрос по документам. Ну или дописать в модуль документа строку с записью цены в справочник и перепровести нужные документы. Ну или средствами скуля сделать запрос с записью в какую-то табличку, из которой потом брать и записывать в справочник (можно и напрямую в справочник если есть достаточные знания скуля и структуры 1С).
Надоело перечислять. Думаю и так есть из чего выбирать.
68 Vladal
 
30.07.12
13:58
(67) Нет. Я уже всё сделал. Спасибо.
Заполнил справочник цен на дату. Потом документ назначениеЦен перенес в 8-ку, история вроде перенеслась.
Требовать и эффективности, и гибкости от одной и той же программы — все равно, что искать очаровательную и скромную жену... по-видимому, нам следует остановиться на чем-то одном из двух. Фредерик Брукс-младший