Большие проблемы с производительностью с Oracle DataReader в .Net - PullRequest
1 голос
/ 10 ноября 2010

У меня есть несколько процедур Oracle, которые генерируют / возвращают большое количество данных, которые мне нужно записать в файл.В настоящее время я пытаюсь достичь с помощью чтения данных.Кажется, работает, я успешно сгенерировал файл 479mb без каких-либо проблем.Прошло менее 4 минут с момента, когда я получил dataReader, чтобы завершить файл.

Но читатель данных, который я получаю для определенной процедуры, сканирует .Это невероятно медленно.Я изменил свой код, чтобы попытаться получить лучшее представление о том, что происходит ....

System.Diagnostics.Debug.Write("Performing .Read() on DataReader: ")
Dim d1 As DateTime = DateTime.Now
Dim result As Boolean = myDataReader.Read()
Dim ts As TimeSpan = DateTime.Now.Subtract(d1)
System.Diagnostics.Debug.WriteLine(ts.ToString)

Интересно, что мой вывод выглядит примерно так:

Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:00:00
Performing .Read() on DataReader: 00:07:33.5037500

Я действительно в растерянности, что делать дальше.Я не вижу ничего уникального или необычного в строке, которая занимает 07: 33.5037500.Есть предложения?

РЕДАКТИРОВАТЬ:

Спасибо за ответы всем.Во-первых, насколько я могу судить, исключений не выбрасывается.Как и предполагалось, я взглянул на эту конкретную процедуру, которая демонстрирует поведение выше, и в то время как процедура является смехотворно массовой;но, похоже, он использует много курсоров, чтобы заполнить временную таблицу оракула.Возвращаемым курсором ссылки является SELECT * FROM этой временной таблицы.

Я пишу блок PL / SQL, который откроет этот курсор, чтобы увидеть, существует ли проблема с производительностью при удалении кода .Net.... надеюсь, это поможет;но если у вас есть какие-то дополнительные мысли, это будет высоко оценено.

Еще раз спасибо.Похоже, что это проблема PL / SQL, а не проблема .NET.

Ответы [ 3 ]

3 голосов
/ 10 ноября 2010

Что на самом деле делает база данных?

Для запроса с GROUP BY или ORDER BY может потребоваться сформировать полный набор результатов, а затем отсортировать / агрегировать его перед возвратом строки. Запрос, сканирующий большую таблицу, может найти 50 строк в первой паре блоков, а затем прочитать еще сто тысяч блоков, прежде чем найдет другой.

Я предлагаю вам проигнорировать код VB и опубликовать код базы данных.

2 голосов
/ 10 ноября 2010

Я предполагаю, что когда вы говорите «конкретная процедура», вы имеете в виду, что вы вызываете хранимую процедуру Oracle, имеющую параметр OUT, который является REF CURSOR. Затем ваш DataReader извлекает данные из курсора, возвращаемого процедурой. Это тот случай?

Если это так, можете ли вы исключить код .Net и написать блок PL / SQL, который вызывает процедуру и извлекает все данные из курсора, чтобы проверить, действуете ли вы там так же? Oracle не материализует данные при открытии курсора - он материализует результаты, когда клиент извлекает данные. Таким образом, вполне возможно, что Oracle придется проделать немалую работу для извлечения N-й строки, если она должна материализовать и отфильтровать кучу данных, прежде чем найдет N + 1-ю строку. Если вы видите такое же поведение в PL / SQL, работающем в базе данных, это почти наверняка происходит. Если вы не видите проблем в блоке PL / SQL, значит, что-то должно происходить на среднем уровне.

1 голос
/ 10 ноября 2010

Просто пара общих комментариев для исходной версии вашего вопроса:

Если вы используете встроенные классы провайдера System.Data.OracleClient для Microsoft .NET Framework, выможет получить лучшую производительность от Собственный обновленный провайдер Oracle .NET .

Если время меняется вокруг каждого прогона, возможно, сборщик мусора .NET запускает некоторыеиспользование памяти, которое не видно в вашем примере (то есть, если многие объекты создаются и выбрасываются).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...