Есть база 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, Спасибо! Дало хороший выигрышь по времени.
Вот что получилось:
...
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 сек. снизилось до долей секунды.
(9) Эх, точно! Единственно, что не понимаю , почему вы все таки добавляете построчно.
Можно же
Array = COMSafeArray.Unload();
Для i=0 по КоличествоКолонок-1 Цикл
НашаТаблица.ЗагрузитьКолонку(Array.Получить(i), НашаТаблица.Колонки[i].Имя);
КонецЦикла;
(10) Я тоже сначало так думал, но тогда придется сначало транспонировать массив, т.к. Array[n] - это элементы массива, в котором содержатся данные не колонки, а строки (т.е. аналогично строке таблицы).
(2) cool.vlad4.
Не хотелось бы использовать внешние компоненты.
(3) cool.vlad4.
Не знаю как насчет параметров ADO (не знаю как и где их смотреть), но запросы выполняются быстро, непосредственная работа с набором данных RecordSet (например, поиск записей в наборе или фильтр) происходит тоже быстро. Но вот перебор всех записей и заполнение таблицы... Запись цикла в строку несколько ускоряет выгрузке, но все же.
(5) параметров у ADO дофига, сейчас лень опять все писать/рассказывать. Поищи в инете, также была здесь публикация справки ADO, а также на сайте script-coding.info
(12) Странно, выигрыш должен быть. Покажите код или попробуйте так (цикл записан в одну строку чтобы не создавать тормоза отладки, так как в вашем случае будет 180 тыс. переходов к строке):
Выборка = Соединение.Execute(ТекстЗапроса);
Если Выборка.EOF() = 0 Тогда
КоличествоКолонок = Выборка.Fields.Count - 1;
ТЗ = Новый ТаблицаЗначений;
Для Сч = 0 По КоличествоКолонок Цикл
ИмяКолонки = Выборка.Fields(Сч).Name;
ТЗ.Колонки.Добавить(ИмяКолонки);
КонецЦикла;
Данные = Выборка.GetRows().Выгрузить();
Для Каждого Стр Из Данные Цикл Н = ТЗ.Добавить(); Для Сч = 0 По КоличествоКолонок Цикл Н[Сч] = Стр[Сч] КонецЦикла КонецЦикла;
КонецЕсли;
Проблема в поле, получаемом через XQuery. Как только оно появляется в запросе, время получения полей из АДО вырастает на 2 секунды. А таких полей полей у меня 12. Помогло решение - сбросить выборку во временную таблицу, а потом уже из нее читать.
В одном месте выигрываем, в другом - проигрываем. Создание временной таблицы занимает столько же времени, сколько раньше занимало получение значений из ADO Recordset. Похоже, что MSSQL открывал неполный рекордсет и искал новые строки в процессе обхода этого рекордсета. Сейчас же он ищет все строки и пишет их во временную таблицу, на что тратит аналогичное время.
2023 год на дворе, а грабли те же. Стояла задача перенести код работы со старой (обычные формы) программы на новую (клиент-серверный) - проблем особых нет. Код перенес. Но почему то в старой программе он отрабатывал, например, минуту, а в новой - 10 минут.
И проблема была именно в чтении Recordset. Переделка на GetRows - никак не помогла. Т.к. в сумме время одинаковое что при последовательном чтении, что при выгрузке в таблице.
Решение проблемы (в моем случае помогло) - замена провайдера для работы с ADODB:
Добрый вечер , 2024 год на дворе.
Задача : Получение данных их БД informix через - ADODB.Connection, выполнение 6000 запросов с получением 135 000 строк.
Обход ADODB.Recordset через Rs.MoveNext() - 140 сек, через Rs.GetRows() - 90 сек. Замеры выполнялись 5 раз.