Вопрос

У меня ужасная производительность при чтении данных из объекта OracleDataReader по сравнению с MS SQL Server.Это почти в 10 раз медленнее, что недопустимо.

Ниже приведен пример тестового кода, который используют оба теста.Какой наиболее оптимальный способ чтения данных из OracleDataReader, есть ли лучший способ, чем показанный ниже?

Мне трудно поверить, что ODP.Net не может даже сравниться с SqlClient.

ОБНОВЛЯТЬ:Я сузил проблему до извлечения текстовых полей.По какой-то причине ODP.Net в этом ужасен.Есть идеи, как это исправить?

void ReadData(System.Data.IDataReader dr, int maxRows)
 {
     ArrayList rows = new ArrayList(maxRows > 0 ? maxRows : 1000);

     object[] row;

     int rowsRead = 0;
     while (dr.Read() && ((maxRows == -1) || (rowsRead++ < maxRows)))
     {
         row = new object[dr.FieldCount];
         dr.GetValues(row);

         rows.Add(row);
     }
     rows.Clear();
 }

Примечания):

  • Пробовал экспериментировать с FetchSize, большой разницы не почувствовал.

  • Здесь проблема не в времени выполнения запроса, а в извлечении данных.

  • Структуры данных в обеих базах данных идентичны.

  • Пробовал комбинацию DataAdapter/DataSet с аналогичными результатами.

Это было полезно?

Решение

На самом деле мы связали эту проблему с использованием столбцов CLOB для хранения строковых данных типа nvarchar(MAX).

Oracle признала, что в их программном обеспечении OCI есть проблемы с CLOB.По умолчанию они пытаются получить CLOB так же, как и очень большой BLOB.Они настраивают указатели, пытаются выполнить пейджинг и т. д.Конечно, такое поведение по умолчанию снижает производительность, когда дело касается обычного текстового поля размером ~200 символов.Фактически вы отключите это поведение, установив для LOBFetchSize значение -1.Таким образом, он захватит содержимое CLOB за один проход.Затем все начинает летать, и вы получаете очень хорошую производительность.

Несмотря на это, у нас продолжали возникать проблемы.Мы подтвердили утечки памяти и ошибки ссылок на память в программном обеспечении OCI до версии 11.2.Но 11.2, похоже, работает нормально как в 32-, так и в 64-битных сценариях.

Таким образом, установка LOBFetchSize на -1 была средством улучшения производительности.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top