|
Подскажите с записью в MS SQL | ☑ | ||
---|---|---|---|---|
0
Garkin
07.05.13
✎
22:37
|
Есть рабочая процедурка записи таблицы контрагентов в SQL
Процедура ДобавитьКонтрагентов(Тз); Recordset = Новый COMObject("ADODB.RecordSet"); Recordset.ActiveConnection=Connection; ТекстЗапроса= "SELECT * FROM customer"; Recordset.CursorType=3; Recordset.LockType=3; Recordset.Open(ТекстЗапроса); БезПоиска=Ложь; Если Recordset.BOF=Истина Тогда БезПоиска=Истина; КонецЕсли; Нпп=0; Для Каждого Тс Из Тз Цикл Нпп=Нпп+1; Состояние("Контрагенты "+Нпп); Если ЗначениеЗаполнено(Тс.Контрагент) = Ложь Тогда Тс.Контрагент=Справочники.Контрагенты.ПустаяСсылка(); КонецЕсли; Если БезПоиска=Истина Тогда Recordset.AddNew(); Иначе Если Recordset.BOF=Ложь Тогда Recordset.MoveFirst(); Recordset.Find("id_customer='" +Тс.Контрагент.Код + "'"); КонецЕсли; Если Recordset.EOF=Истина Тогда Recordset.AddNew(); КонецЕсли; КонецЕсли; Recordset.Fields("id_customer").Value = Тс.Контрагент.Код; Recordset.Fields("name_customer").Value = Лев(СокрЛП(Тс.Контрагент.Наименование),100); Recordset.Fields("id_grp").Value = Тс.Контрагент.Родитель.Код; Recordset.Fields("unn").Value = Лев(СокрЛП(Тс.Контрагент.УНП),9); Если ЗначениеЗаполнено(Тс.Район) Тогда Recordset.Fields("id_raj").Value =Тс.Район.Код; КонецЕСли; Recordset.Fields("id_sales").Value = Тс.СотрудникКод; Recordset.Update(); КонецЦикла; Recordset.Close(); КонецПроцедуры Работала с Postgre достаточно шустро, перевели на MS SQL жутко тормозит вот в этом месте: Recordset.Find("id_customer='" +Тс.Контрагент.Код + "'"); Подскажите где что пнуть чтобы ускорить? |
|||
1
sda553
07.05.13
✎
22:47
|
(0) пнуть замер производительности в конфигураторе и сказать в каких строках этой портянки он наибольший
|
|||
2
Garkin
07.05.13
✎
22:49
|
(1) вот здесь
Recordset.Find("id_customer='" +Тс.Контрагент.Код + "'"); |
|||
3
sda553
07.05.13
✎
22:51
|
(2) Я бы вообще не использовал find, кол надо переделать. Если малой кровью, то seek надо использовать
|
|||
4
MaxS
07.05.13
✎
22:52
|
(2) зачем нужен SQL сервер, если используется такая конструкция - поиск в цикле по одной строке?
Нужно оптимизировать и искать одним запросов всё. |
|||
5
sda553
07.05.13
✎
22:53
|
тут наоборот надо обходить recordset в цикле, а искать в тз
|
|||
6
sda553
07.05.13
✎
22:54
|
(5) не читать, это я глупость сказал.
Обходим так же тз и на каждую строку делаем запрос с where |
|||
7
MaxS
07.05.13
✎
22:54
|
И это можно оптимизировать и выводить каждое 100-е, например. Состояние("Контрагенты "+Нпп);
|
|||
8
MaxS
07.05.13
✎
23:11
|
Максимальная скорость будет, если предварительно подготовить список кодов из 1С и одним запросом у SQL узнать наличие контрагентов. Получить в 1С массив существующих на SQL контрагентов.
Из Тз, к котором есть контрагенты и из массива существующих, нужно получить результат запроса с информацией о всех контрагентах, которых нет в SQL. Вместо Тс.Контрагент.Код использовать ВыборкаДетальныеЗаписи.Код. и т.п. |
|||
9
Garkin
07.05.13
✎
23:26
|
(3)-(8) спасибо. Но все равно непонятно почему в Постгре это нормально работает, а на MS SQL такие тормоза?
|
|||
10
timurhv
07.05.13
✎
23:31
|
(9) Пример приведи сколько было элементов в справочнике "Контрагенты" во времена Постгри и сколько сейчас.
|
|||
11
Garkin
07.05.13
✎
23:41
|
(10) Да одинаково, порядка 1000. В постгре выгружается секунд 20, в MS SQL минут 10.
|
|||
12
МихаилМ
07.05.13
✎
23:45
|
у Вас перепутана обработка данных с получением и выводом
данных. полный винигрет. сответственно если Вы хотите управлять производительностью и надежностью разбейте метод на 3 метода 1) получение данных из бд 2) обработка данных 3) запись данных никогда не используйте * в запросе в рабочем коде выбирайте только нужные для обработки поля. иначе кто-то может добавить поля типа image * только для отладки мыслите множествами, а не строками данные выбирайте множеством. обработку данных делайте множеством не бойтесь "лишних" циклов если методов несколько: правильней вызвать метод для каждой сущности чем несколько методов для каждой строки. сответственно 1) запросом получите данные в ТЗ без Тс.Район.Код , Тс.Контрагент.Наименование 2) обработайте до вида пригодго для загрузки в БД 3) загрузите в временную таблицу обработайте данные на пригодность на стороне субд результат обработки в ВТ ошибок выполните обновление получите информацию о результате и обработайте |
|||
13
Garkin
07.05.13
✎
23:55
|
(12) Спасибо, т.е. так чтоб ничего не делать не получится :(, жаль.
|
|||
14
Jaap Vduul
07.05.13
✎
23:58
|
А что ж ты хочешь?
У тебя серверный курсор с оптимистической блокировкой. Ты своим find кучу телодвижений на сервере вызываешь. С точки зрения минимальной переделки - замена find на filter |
|||
15
Sammo
08.05.13
✎
06:01
|
Имхо, здесь вообще можно обойтись без подобного использования recordset, особенно при количестве в 1000 штук.
Собираем текст со скулевым запросом, где на каждую строку ТЗ делаем select where. Если его нет, то insert. Если есть и надо все равно - update. И потом запускаем готовую портянку с полученным запросом. Command.CommandText = полученный текст запроса. RecordSet = Command.Execute() |
|||
16
sttt
08.05.13
✎
06:29
|
попробуй в транзакции сделать
|
|||
17
sttt
08.05.13
✎
06:31
|
и Тс.Контрагент.Код получай в самом запросе а не в цикле из тз
|
|||
18
ЧеловекДуши
08.05.13
✎
07:26
|
Используй "IINSERT INTO table_name
VALUES (value1,value2,value3,...)", http://www.w3schools.com/sql/sql_insert.asp с командой по 250 строк. (ну мин 100) |
|||
19
ЧеловекДуши
08.05.13
✎
07:27
|
(16) А транзакция чем поможет? :)
|
|||
20
Karavanych
08.05.13
✎
08:12
|
хм я вообще, я UPDATE и INSERT INTO юзал.
но если ты хочешь дальше использовать курсор, то я бы выбрал только нужные записи в select + order by id_customer по массиву кодов контрагента, затем отсортировал твою ТЗ так же по кодам контрагента, и по порядку перебирал записи - считай find вообще не нужно бы были использовать, потому что у тебя они по порядку обе ТЗ отсортированы одинакого, просто берешь следующую строку и все. (с оговоркой что проверка на существование этих записей в обеих таблицах - сделана,если нет - ничего страшного, просто надо шаг в существующей сделать лишний). |
|||
21
sttt
08.05.13
✎
08:51
|
(19) вроде как помогает ускорить.
еще можно журнал транзакций шринк сделать или вставлять записи без журнала |
|||
22
sttt
08.05.13
✎
08:53
|
ALTER DATABASE МойБаза SET RECOVERY SIMPLE
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |