|
Как ускорить поиск по реквизиту | ☑ | ||
|---|---|---|---|---|
|
0
vde69
05.02.10
✎
14:44
|
есть сторонняя система, в 1с из нее получаем таблицу ТЗ примерно в 50 тыс строк, далее надо связать контрагентов и договора (по доп полю), сейчас в базе примерно 200тыс договоров, текущий алгоритм стал долго работать (1-2 часа).
Сейчас алгоритм такой: из ТЗ выгружаем колоку с кодами контрагентов и сворачиваем, далее ее дополняем колонкой и заполняем эту колонку (получаем кеш таблицу), проходим основную ТЗ и заполняем поле Контрагент (на основании кеш таблицы), алгоритм заполнения однопроходный цикл. далее так-же заполняем договора, банки, счета и т.д. на сколько я понимаю сейчас у нас проблеммы в размере ТЗ нужна идея какой-то хитрой связи, я пока склоняюсь к варианту создания временной таблицы в скуле и прямом джойне, |
|||
|
1
Sadovnikov
05.02.10
✎
14:47
|
(0) "я пока склоняюсь к варианту создания временной таблицы в скуле и прямом джойне" - сдается мне, что это самое правильное решение...
|
|||
|
2
vde69
05.02.10
✎
14:49
|
(1)от тебя другого и не ожидал :)
есть еще такой вариант - хранить внутренний_ID обьекта в сторонней системе, и после получения ТЗ востанавливать ссылку по ID |
|||
|
3
DrZombi
гуру
05.02.10
✎
14:56
|
(0)А поподробнее, про запрос?
Что именно ты хочешь получить в итоге? И зачем все в одной? Разве не проще все поручить самому скулю, а там ужо только результат получить? |
|||
|
4
kiruha
05.02.10
✎
14:56
|
скидывай во временную таблицу дбф или sql .
Индексируем. Потом прямыми - максимум 2 минуты. |
|||
|
5
vde69
05.02.10
✎
14:59
|
(3) стороння база на другом серваке, а прямые джойны для разных серверов не гуд.
|
|||
|
6
Жан Пердежон
05.02.10
✎
15:01
|
(0) >> получаем таблицу ТЗ примерно в 50 тыс строк, далее надо связать контрагентов и договора;
чего с чем связать, что в таблице то? |
|||
|
7
Mikeware
05.02.10
✎
15:02
|
(6) Веревкой связать контрагентов. И бирку (договор о погребении) к пятке...
|
|||
|
8
DrZombi
гуру
05.02.10
✎
15:04
|
(5)Да... согласен, но зато быстро :)
А чем не через ОЛЕ + в олешной базе запрос? |
|||
|
9
vde69
05.02.10
✎
15:06
|
(6)
// вот эта функция вызывается 1 раз для каждого УНИКАЛЬНОГО договора // примерно 10 тысяч раз // // подобных полей связи около 10 // Функция СвязатьДоговор(ТабДоговоров, Контрагент, НомерДоговора, ДатаДоговора, НазваниеДокумента, Connection,УИД,ТипД,ДатаСчФ="") Договор = ""; Если ПустоеЗначение(Контрагент) = 1 Тогда _Сообщить("Пустой Контрагент"); Иначе Если НомерДоговора = "" Тогда _Сообщить("Пустой номер договора, для контрагента <" + Контрагент + ">","!"); Иначе Договор = СоздатьОбъект("Справочник.Договоры"); ТабДоговоров.ВыбратьСтроки(); _УИД = Число(УИД); Пока ТабДоговоров.ПолучитьСтроку() = 1 Цикл Если ТабДоговоров.УИД = _УИД Тогда Договор.НайтиЭлемент(ТабДоговоров.Ссылка); Если (СокрЛП(Договор.НомерДоговора) = НомерДоговора) //отменил для скорости, по сколько расхождения типа Договор.НомерДоговора = "67-F/08" НомерДоговора = "67-F/08 от 17.03.2008" И (Договор.ДатаДоговора = ДатаДоговора) И (Договор.Владелец = Контрагент.ТекущийЭлемент()) Тогда Иначе _Сообщить("есть расхождения по договору с ID="+УИД+" ["+Договор+";"+Договор.Владелец+"]","!"); КОнецЕсли; Прервать; КонецЕсли; КонецЦикла; // Если (СокрЛП(Договор.НомерДоговора) <> НомерДоговора) // ИЛИ (Договор.ДатаДоговора <> ДатаДоговора) // ИЛИ (Договор.Владелец <> Контрагент.ТекущийЭлемент()) Тогда Если (Договор.УИД<>Число(УИД)) ИЛИ (Договор.ТипД<>ТипД) Тогда // не нашли, надо создать // сначало получим данные по нему Попытка Command = СоздатьОбъект("ADODB.Command"); Command.ActiveConnection = Connection; Command.CommandType=1; Command.CommandTimeOut = 300; ДатаД = "" + ДатаЧисло(ДатаДоговора) + "." + ДатаМесяц(ДатаДоговора) + "." + ДатаГод(ДатаДоговора); Command.CommandText=" EXEC fk_prDocs " + Уид + ","+ТипД; Set = Command.Execute(); Исключение _Сообщить("Ошибка получения данных по договору! №" + НомерДоговора + " от " + ДатаД,"!"); _Сообщить(ОписаниеОшибки()+" m2","!"); Возврат ""; КонецПопытки; Договор.Новый(); Договор.Владелец=Контрагент; Договор.УстановитьНовыйКод(); Договор.АвтоОбработкаНДС = ?(Константа.АвтоКнигаПокупокПродаж = Да, 1, 0); Если ДатаСчф<>"" тогда Договор.Наименование = НазваниеДокумента + " №" + НомерДоговора + " от " + ДатаСчФ; Иначе Договор.Наименование = НазваниеДокумента + " №" + НомерДоговора + " от " + ДатаДоговора; КонецЕсли; Договор.НомерДоговора = НомерДоговора; Договор.ДатаДоговора = ДатаДоговора; Договор.ВидДоговора = глЗначениеПоУмолчанию("ОсновнойВидДоговоров"); Договор.УИД=Число(УИД); Договор.ТипД=ТипД; Пока Set.EOF()<>-1 Цикл Договор.ДатаВозникновенияОбязательства = Дата(Set.Fields("DateEnd").Value); Прервать; КонецЦикла; Договор.Записать(); ТабДоговоров.НоваяСтрока(); ТабДоговоров.Ссылка = Договор.ТекущийЭлемент(); ТабДоговоров.УИД = Договор.УИД; _Сообщить ("Создан новый договор <" + Договор + "> для контрагента <" + Контрагент + ">"); КонецЕсли; Если (Договор.УИД<>Число(УИД)) ИЛИ (Договор.ТипД<>ТипД) Тогда _Сообщить("Не связался договор <" + НомерДоговора + "> для контрагента <" + Контрагент + ">","!"); Договор = ""; КонецЕсли; КонецЕсли; КонецЕсли; Если Договор="" Тогда Возврат "" Иначе Возврат Договор.ТекущийЭлемент(); КонецЕсли; КонецФункции |
|||
|
10
vde69
05.02.10
✎
15:06
|
(8) другая база дельфовая :)
|
|||
|
11
Mikeware
05.02.10
✎
15:08
|
(9) Букв много. Что сделать-то надо?
|
|||
|
12
Жан Пердежон
05.02.10
✎
15:08
|
(9) а чего с чем связывать и что в таблице - так и не ясно)
пока только запрос в цикле виден |
|||
|
13
vde69
05.02.10
✎
15:14
|
(12) запрос в цикле - это только для вновь создаваемых элементов получение данных из сторонней системы
|
|||
|
14
genosse
05.02.10
✎
15:15
|
(0) Перефразируй (точнее сформулируй) сам вопрос. Понять тут вообще ничего не реально.
получаем таблицу 50000 -> нужно связать контрагентов с договорами их 200000 -> текущий механизм долгий :) |
|||
|
15
vde69
05.02.10
✎
15:18
|
вот что я получаю из сторонней системы:
/*Объект: fk_prKomis1C Тип: Процедура Описание: Формирует данные для создания в 1С проводок "Начисление комиссии", "Удержание комиссии" Идентификатор: 10021 Использование: Параметры: Входные: @dt_Beg char(10) дата начала, @dt_End char(10) дата завершения формат 'dd.mm.yyyy' Выходные: Возврат: таблица данных id_ac - id счёт-фактуры ndoc - номер счёт-фактуры nds - ндс по счёт-фактуре id_Cli - id клиента id_Deb - id дебитора clinn - инн клиента debinn - инн дебитора Rekvizit - номер договора с клиентом DateBeg - дата начала договора DateEnd - дата завершения договора (если нет - то NULL) Schet - банковский счёт факторинга Ident - идентификатор (начисленные комиссии) sm_AU_Nach - КомАУ sm_AUFin_Nach КомАУфин sm_PrcZaFin_Nach КомФН sm_StrafNach - штрафы (оплаченные комиссии) sm_AU_Opl - КомАУ sm_AUFin_Opl КомАУфин sm_PrcZaFin_Opl КомФН sm_StrafOpl - штрафы dt_inp - дата создания с.ф. в нашей системе --------------------------------------------------- нужно создать документы, для этого нужно по ИНН найти контрагентов, по дате иномеру договора найти договора |
|||
|
16
genosse
05.02.10
✎
15:21
|
(15) Замер производительности в каком месте дает наибольший процент?
Что оптимизируем? Надо сузить круг подозреваемых .) |
|||
|
17
orefkov
05.02.10
✎
15:21
|
тз во врем.табличку и запросом ее, запросом.
|
|||
|
18
vde69
05.02.10
✎
15:27
|
(16) явных лидеров нету, код и так оптимизировали несколько раз
|
|||
|
19
genosse
05.02.10
✎
15:31
|
(18) Обе базы скуль? Документы все новые или нужно проверить на наличие изменений в старых + залить новые?
|
|||
|
20
vde69
05.02.10
✎
15:33
|
(19) обе SQL, но разные 2000 и 2005, при ждойне между серверами индексы не используются, по этому все сделать на одном сервере нельзя.
алгоритм пересоздания документов вполне нормально работает, медлено поиск и создание справочников |
|||
|
21
genosse
05.02.10
✎
15:36
|
(20) Можно сделать тригер на источнике и переносить только созданные и измененые. Опять же и структуру базы не затронет.
|
|||
|
22
Asirius
05.02.10
✎
15:38
|
(15) Зачем нужна таблица ТабДоговоров? Почему не сделать индекс по Договор.УИД?
|
|||
|
23
vde69
05.02.10
✎
16:05
|
(22) для того, что-бы по несколько раз не искать
|
|||
|
24
Asirius
05.02.10
✎
16:25
|
(23) Так ты и каждый раз договор выбираещь
>>Договор.НайтиЭлемент(ТабДоговоров.Ссылка); Договор.НайтиПоРеквизиту("УИД",Уид) будет практически с такой же скоростью работать |
|||
|
25
vde69
05.02.10
✎
17:16
|
(24) проверь :)
кроме того у меня таблица сильно меньше всего справочника |
|||
|
26
МихаилМ
05.02.10
✎
17:55
|
тормоза от подхода решения задачи.
обрабатвайте данные множествами а не записями. сответственно желательно иметь метод получения из другой ИБ не обной записи, а множества. и опять же сопоставления (формировани выборки) удобней сделать на сервере а запись на клиенте из сображений понятности кода . |
|||
|
27
vde69
07.02.10
✎
20:28
|
(26) получаем выборку одним запросом, далее обращения к базе идут только для НОВЫХ элементов
сопостовление на сервере для 7.7 это КАК? |
|||
|
28
leshikkam
07.02.10
✎
20:32
|
(27) linked server может быть?
|
|||
|
29
Garkin
07.02.10
✎
21:03
|
(9) Спрошу на всякий случай.
_УИД = Число(УИД); Пока ТабДоговоров.ПолучитьСтроку() = 1 Цикл Если ТабДоговоров.УИД = _УИД Тогда ........ Прервать; КонецЕсли; КонецЦикла; Это точно работает быстрее чем ТабДоговоров.НайтиЗначение( ? |
|||
|
30
Garkin
07.02.10
✎
21:23
|
+(29)
Еще непонятно зачем надо Договор.НайтиЭлемент(ТабДоговоров.Ссылка); Разве Договор=ТабДоговоров.Ссылка недостаточно? |
|||
|
31
Garkin
07.02.10
✎
22:32
|
(0) Отсортируй ТЗ по "доп - полю" - избавься от кэш таблицы.
Да еще непонятно, сначала ищем клиентов, потом ищем договора. Договор разве не определяет однозначно клиента? |
|||
|
32
vde69
08.02.10
✎
08:34
|
(31) в 1с - да, но в сторонней системе нет, и тут идет контроль сторонней системы
(30) если договор надо записать, то все равно нужна такая конструкция (29) принимается, посмотрю подробнее |
|||
|
33
Garkin
08.02.10
✎
09:06
|
(32)
"в 1с - да, но в сторонней системе нет, и тут идет контроль сторонней системы " Ну и фик с ним, найди договор, а потом контролируй совпадает ли владелец договора в 1С с клиентом в сторонней система. "если договор надо записать, то все равно нужна такая конструкция " - что-то я не наблюдаю где ты в (9) записываешь найденный договор, ты от нас что-то скрываешь? "принимается, посмотрю подробнее" - в топку, см (31). Избавься от кэш таблицы. |
| Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |