Совсем не понимаю...
Совсем не понимаю...
Простая функция (код не мой - можно тапки бросать мимо):
Public Function fillDT(ByVal sql As String) As DataTableDim oraCN As New OracleConnectionDim oraDA As New Oracle.DataAccess.Client.OracleDataAdapterDim DT As New DataTableDim oraCmd As New OracleCommandTryoraCN.ConnectionString = _connectionStringoraCN.Open()Debug.Print(sql)oraCmd.CommandText = sqloraDA.SelectCommand = oraCmdoraDA.SelectCommand.Connection = oraCNDT.Columns.GetEnumerator()oraDA.Fill(DT)Return DTCatch ex As ExceptionEmail.SendMailMessage(_senderAddress, My.Settings.emailErrorRecipient, "", "", _My.Computer.Name.ToString & ": " & _"error in: DANenprod1." & _System.Reflection.MethodBase.GetCurrentMethod.Name.ToString, _sql & ControlChars.CrLf & _ex.ToString)Return DTFinallyoraCN.Dispose()End TryEnd Function
Успешно работала несколько лет.
Никаких изменений в код мною не вносилось.
Передаваемая СКЛ-строка - сложная, но относительно быстрая - в дбФорже-студии выполняется за 1.578 сек.
Что могло измениться так, что oraDA.Fill(DT) не может выполнится в течении 12-15 часов?
Ошибок выполнения или таймаутов - нет.
Данных - да, много, но ведь работало...
Хммм...
Север точно отдает данные...
Весь набор строится... за пару секунд...
Весь набор можно читать... если читать оракловским реадером - где-то за 56 секунд... это трансфер по сети и навигация по записям...
Весь набор можно загнать в таблицу... построчно... читаем поля, формируем строку, добавляем в таблицу... где-то 10 минут...
Что-же, пилять, билли забубенил в винде, что процессу не хватает 16 часов?..
За выходные успел померить время и объем данных которое перекачиваются по запросу.
Данных "не много" - 130 Мб... время перекидывания с сервера на клиента - 2 часа 39 минут...
С утра, пока никого не было, шеф запустил запросик и за 20 минут все получил...
Сейчас - все в работе и... все, задница - полтора часа,,,
Как решать - не представляю...
Могу понизить объем данных для перекачки где-то в два раза, но это только за счет отсечения
условно-устаревших данных...
Могу еще извратится с хранением основного массива на клиенте и переброской дельты, но
тут работы дохрена... и в пустую - скоро переход на новую систему,,,
В общем - пока на все плюну... даже на недоделанный репорт... и погляжу в аутентификацию
пользователей и лицензирование под ВKФ...
Проблемы с железом не являются моими проблемами.
А так - да, "исключил" - не хватает ресурсов (памяти) на сервере для всех юзверей, он свопит по черному и отдает все медленно.
Выяснилась еще одна интересная штука - если экспортировать в ЦСВ прямо на сервере - процесс занимает всего секунд 10...
Получается, что где-то что-то с сеткой... но по сетке все летает - 60-70 мб...
Ни черта не понимаю...
Померял реальный трансфер с сервера на клиента.
Общее время трансфера - чуть больше 5 секунд. Остальные 49 минут - чтение полей данных из стрема...
Не понимаю что поменялось настолько, что все начало тормозить...
Блин, видимо придется тестить время чтения каждого отдельного поля... пипец...
Кажется нашел возможную причину....
Не уверен, но...
- одно из полей имело значение NULL
- после замены значения поля протестировал загрузку по отдельным полям - время сократилось до 8 минут.
Никак не могли быстро обработать NULL?
Надо посмотреть что будет на стандартной загрузке таблицы...
Кажется Я вообще ничего не понимаю...
Есть Оракла 10Г на линуксовой машине.
Стоит. Работает. Ну как может так и работает.
Есть несложная процедура обновляющая несколько неприятно больших таблиц.
В результате всех обновлений в интересующей таблице получается 35К записей по 173 поля. Длинна отдельной записи - <5К. Всего около 170 Мб.
Перебрал все возможные варианты чтения и выбрал самый быстрый - датареадером, по отдельным полям, с непосредственным указанием типа - GetString(i), GetNumeric(i), GetDateTime(i).
Процесс загрузки данных занимает 33 минуты... это вместо нескольких часов по филл(дататабле)...
Распределение времени следующее:
Read Time : 00:00:09.9054802
Value Time : 00:32:10.6379357
DT op Time : 00:00:01.8005709
Execution time (FL2DT)00:32:28.2043131
String : 00:04:28.2550130 (00:00:03.1365717/per field)
Numeric : 00:13:45.4187597 (00:00:03.2605435/per field)
DateTime : 00:13:56.9372428 (00:00:03.2190423/per field)
Первая строка - время трансфера с сервера и нарезания на строки.
Вторая строка - время извлечения данных из строки в поля датаров...
Третья строка - время операций с дататабле.
Ниже - распределение времени по типам полей (по сумме 35К записей).
Еще две цифирьки:
Execution time (DT2XML)00:00:11.0342339
Execution time (XML2DT)00:00:06.3511341
Первая строка - время записи схемы и данных (35К строк) из дататабле в файл (на локальный диск)
Вторая строка - время чтения схемы и данных (35Кстрок) из файла в дататабле.
Размер хмл-файла на диске - 250 Мб.
У меня снова тот же вопросик - Что сумели поменять так, что чтение данных в таблицу занимает полчаса вместо 7 секунд?
Я просто на понимаю - что можно было поменять в плане почти автономной Оракле.ДатаАкксесс.Длл чтобы она начала работать на несколько порядков медленнее?
Проверь firewall, а точнее отключи его (если есть такая возможность)
Внутренний файрволл - выключен.
Есть внешний, доставляющий много хлопот, но вроде как на данную ситуацию не влияющий.
Согнал время до 7 минут.
При этом апдейт таблицы - 1.5 мин,
Загрузка с Оракла - 4.5 минуты.
Загрузка в ДатаТабле из файла - 5-6 секунд.
Ээээ... дамп файла на сервере - 5-8 секунд и еще 5-7 секунд - перекачка по сетке...
Завтра надо слепить процедурку экспорта файла на сервере и закачку его в таблицу... будет около 2-х минут.
Ну а потом мне надо будет изворачиваться - имеющийся код обмолачивает данные на клиенте несколько часов... как сделать за пару секунд - знаю, но времени на писанину не дают...
Пропорционально.
Там где выведено время обработки поля - это на 35К записей, на 10 записей - будет в 35К раз меньше.
Но мне нужен весь объем данных.
Если была мысль закачать пакетами по 10-100-1000 строк - будет много медленнее, чем целиком.
Данных "не много" - 130 Мб... время перекидывания с сервера на клиента - 2 часа 39 минут
это конечно не нормально!
Подозреваю, что может воновата Fill(). Типичное явление на практике, что эта метода влечёт за собой в SQL Server так называемый ASYNC_NETWORK_IO вартетип, в Оракле тоже есть подобный IO Wait.
Как решение обычно предлагается сократить количество строк или модифицировать Fill(). Как, к сожалению не могу так сразу сказать, поскольку другой у меня schwerpunkt
или модифицировать Fill().
------
Снова имеется интересная мысль!
Модифицировать код из Oracle.DataAccess.dll...
Стандартный, работающий в куче приложений....
Оракле тоже есть подобный IO Wait.
-----
Да, но у меня - не используется - стандартная синхронная загрузка.
Просто не понимаю почему читается только 15-17 строк в секунду...
Пусть их 20 в секунду, по 200 полей - 4000 чтений элементов массива в памяти в секунду...
Бред... но именно так и происходит.
На И8080А Я бы это еще понял... но и там Я это делал быстрее...
Нашел.
Можно смеяться, Но дело было так...
Кто-то умный решил что новый станок можно включить в систему элементарно прописав его в базу.
Станок то он прописал, но вот выполняемые им процедуры описал не корректно - в одном тексте
вместо PVB, было написано PV2.
Дальше это PV2 использовалась как часть имени поля... ну так код слеплен - вместо нормального
Трансформ используется сильно синтетическая и предопределенная выборка с последующим
заполнением таблицы данными.
При обращении к таблице за данным полем получался вполне ожидаемый фаулт.
По факту такого безобразия программка должна была сообщать по е-майлу с указанием
кучи деталей об что, где, когда...
Но как обычно сетевики что-то нахомутали с почтовиком и вместо отправления сообщения
получалось отсутствие соединения, которое через пару секунд выливалось по таймауту и
почему-то сопровождалось Socket Error и последующими тормозами по всем операциям с
данными из сети.
Сколько именно система ждала тайм-аутов от мыльного сервера - непонятно - там где процедура
была задействована - там и ждала, но, похоже, как раз все время - 16-20+ часов...
По крайней мере сейчас все по еле-еле но телепается....
Пыххх... Я таки утомился...
И все же работает медленно.
Причем медленно - именно чтение полей из реадера. Все остальное - типа Филл() - еще медленнее.
Пака не понял как ускорить, кроме как скинуть в файл и выкачать один БЛОБ...
Есть какие идеи как быстро перекачать 200Мб из базы в ДатаТабле?