Как ускорить выгрузку данных из объекта RecordSet в ТаблицуЗначений?

1. sannt 1 15.02.12 14:30 Сейчас в теме
Есть база SQL, к которой делаются запросы из 1С с использованием ADO. Получаемые наборы данных могут быть большими (несколько тысяч строк и до 20 полей(колонок)). Соответственно заполнение ТаблицыЗначений в цикле по строкам и полям набора данных может занимать продолжительное время.
Пример:
...
COMRecordSet.Open(ТекстЗапросаSQL);
COMRecordSet.MoveFirst();
While COMRecordSet.EOF = 0 Do
NewString = ValueTable.Add();
For Each Field In COMRecordSet.Fields Do
NewString[Field.Name] = COMRecordSet.Fields(Field.Name).Value;
EndDo;
EndDo;
...

Какие есть способы ускорить процесс выгрузки данных в ТаблицуЗначений?
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
4. shuhard 15.02.12 14:51 Сейчас в теме
9. sannt 1 15.02.12 15:10 Сейчас в теме
(4) shuhard, Спасибо! Дало хороший выигрышь по времени.

Вот что получилось:
...
COMSafeArray = COMRecordSet.GetRows();
Array = COMSafeArray.Unload();
For i = 0 To Array.UBound() Do strArray = Array[i]; NewStr = ValueTable.Add(); For j = 0 To strArray.UBound() Do NewStr[j] = strArray[j] EndDo EndDo;
...

Для набора записей в ~5000 строк и 20 полей время выгрузки с ~9 сек. снизилось до долей секунды.

Вопрос снят.
10. cool.vlad4 2 15.02.12 15:49 Сейчас в теме
(9) Эх, точно! Единственно, что не понимаю , почему вы все таки добавляете построчно.
Можно же
Array = COMSafeArray.Unload();
Для i=0 по КоличествоКолонок-1 Цикл
НашаТаблица.ЗагрузитьКолонку(Array.Получить(i), НашаТаблица.Колонки[i].Имя);
КонецЦикла;
11. sannt 1 15.02.12 20:50 Сейчас в теме
(10) Я тоже сначало так думал, но тогда придется сначало транспонировать массив, т.к. Array[n] - это элементы массива, в котором содержатся данные не колонки, а строки (т.е. аналогично строке таблицы).
2. cool.vlad4 2 15.02.12 14:31 Сейчас в теме
внешняя компонента - GameWithFire .
Таблица = ADOUtils.ADORecordsetToValueTable(RecSet);
5. sannt 1 15.02.12 14:51 Сейчас в теме
(2) cool.vlad4.
Не хотелось бы использовать внешние компоненты.

(3) cool.vlad4.
Не знаю как насчет параметров ADO (не знаю как и где их смотреть), но запросы выполняются быстро, непосредственная работа с набором данных RecordSet (например, поиск записей в наборе или фильтр) происходит тоже быстро. Но вот перебор всех записей и заполнение таблицы... Запись цикла в строку несколько ускоряет выгрузке, но все же.
6. cool.vlad4 2 15.02.12 14:56 Сейчас в теме
(5) попробуй заменить итерацию не по COM объекту, а по объекту 1С-а, если это возможно. (к примеру если известно заранее количество колонок)
7. cool.vlad4 2 15.02.12 14:57 Сейчас в теме
(5) параметров у ADO дофига, сейчас лень опять все писать/рассказывать. Поищи в инете, также была здесь публикация справки ADO, а также на сайте script-coding.info
3. cool.vlad4 2 15.02.12 14:34 Сейчас в теме
Либо сидеть с замером и отладчиком, смотреть в чем дело. Дело может быть в параметрах ADO, в запросе, в получении данных
8. cool.vlad4 2 15.02.12 14:59 Сейчас в теме
открыть http://www.script-coding.com/ADO.html => нажать ctrl-f => набрать курсор и прочитать
12. nicxxx 254 15.08.18 11:38 Сейчас в теме
Не помогает:( Метод GetRows() работает столько же, сколько длится построчное заполнение через fields.item
10 000 строк, 18 колонок
13. SlavaKron 15.08.18 11:56 Сейчас в теме
(12) Странно, выигрыш должен быть. Покажите код или попробуйте так (цикл записан в одну строку чтобы не создавать тормоза отладки, так как в вашем случае будет 180 тыс. переходов к строке):
	Выборка = Соединение.Execute(ТекстЗапроса);
	
	Если Выборка.EOF() = 0 Тогда		
		
		КоличествоКолонок = Выборка.Fields.Count - 1;
		
		ТЗ = Новый ТаблицаЗначений;
		Для Сч = 0 По КоличествоКолонок Цикл
			ИмяКолонки = Выборка.Fields(Сч).Name;
			ТЗ.Колонки.Добавить(ИмяКолонки);
		КонецЦикла;
		
		Данные = Выборка.GetRows().Выгрузить();
		Для Каждого Стр Из Данные Цикл Н = ТЗ.Добавить(); Для Сч = 0 По КоличествоКолонок Цикл Н[Сч] = Стр[Сч] КонецЦикла КонецЦикла;

	КонецЕсли;
Показать
14. nicxxx 254 15.08.18 16:28 Сейчас в теме
Проблема в поле, получаемом через XQuery. Как только оно появляется в запросе, время получения полей из АДО вырастает на 2 секунды. А таких полей полей у меня 12. Помогло решение - сбросить выборку во временную таблицу, а потом уже из нее читать.
15. nicxxx 254 15.08.18 17:12 Сейчас в теме
В одном месте выигрываем, в другом - проигрываем. Создание временной таблицы занимает столько же времени, сколько раньше занимало получение значений из ADO Recordset. Похоже, что MSSQL открывал неполный рекордсет и искал новые строки в процессе обхода этого рекордсета. Сейчас же он ищет все строки и пишет их во временную таблицу, на что тратит аналогичное время.
16. insurgut 207 26.09.23 12:13 Сейчас в теме
2023 год на дворе, а грабли те же. Стояла задача перенести код работы со старой (обычные формы) программы на новую (клиент-серверный) - проблем особых нет. Код перенес. Но почему то в старой программе он отрабатывал, например, минуту, а в новой - 10 минут.

И проблема была именно в чтении Recordset. Переделка на GetRows - никак не помогла. Т.к. в сумме время одинаковое что при последовательном чтении, что при выгрузке в таблице.

Решение проблемы (в моем случае помогло) - замена провайдера для работы с ADODB:

Было (медленно):
СтрокаПодключения = "Driver= {Microsoft Access Driver (*.mdb)};systemDB=" + ПутьКФайлуБД + "GATE.mdw;Dbq=" + ПутьКФайлуБД + "config.mdb;Uid=master;Pwd=пароль";


Стало (заработало шустро):
СтрокаПодключения  =   "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + ПутьКФайлуБД + "config.mdb; Jet OLEDB:System Database=" + ПутьКФайлуБД + "GATE.mdw;User ID=master;Password=пароль;""";
Sashares; +1 Ответить
17. valex1c 26.02.24 23:21 Сейчас в теме
Добрый вечер , 2024 год на дворе.
Задача : Получение данных их БД informix через - ADODB.Connection, выполнение 6000 запросов с получением 135 000 строк.
Обход ADODB.Recordset через Rs.MoveNext() - 140 сек, через Rs.GetRows() - 90 сек. Замеры выполнялись 5 раз.
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот