Запрос Oracle выполняется медленно (или не выполняется) из приложения .NET, но быстро из SQL Developer - PullRequest
10 голосов
/ 07 сентября 2010

Мы используем ODP.NET для выполнения запросов к базам данных Oracle, и обычно он работает нормально. Однако в этой базе данных есть конкретная база данных и конкретное представление, к которому мы просто не можем выполнить запрос из .NET. Например:

SELECT some_varchar_field FROM the_view WHERE ROWNUM < 5;

Если я выполню этот запрос из Oracle SQL Developer, он завершится менее чем за секунду. Если я выполняю идентичный запрос из нашего приложения .NET, использующего ODP.NET, оно зависает и в итоге выдает ошибку «ORA-03135: соединение потеряло контакт». Я думаю, что ограничение всего несколькими строками исключает вероятность того, что это проблема FetchSize.

Существуют и другие запросы, которые я могу успешно выполнить, но они медленнее в нашей программе, чем в SQL Developer. Опять же, я понимаю, что SQL Developer изначально получает данные только для первых 50 строк, но я думаю, что условие ROWNUM исключает это из уравнения.

Что может отличаться в соединении или команде, которые использует Oracle SQL Developer, от той, которую использует наше приложение, что может привести к разнице в скорости?

К сожалению, у меня нет доступа к серверу (кроме как для выполнения запросов Oracle к нему).

Спасибо.

ОБНОВЛЕНИЕ: Я пытался выполнить тот же запрос с поставщиком Microsoft от Oracle, и он выполняется очень быстро. К сожалению, этот поставщик устарел, так что это не долгосрочное решение.

Ответы [ 4 ]

13 голосов
/ 30 октября 2010

Это не имеет ничего общего с провайдером ODP.NET.Проблема заключалась в том, что библиотека, которую мы используем для создания соединений для нас (которая, конечно, не используется Oracle SQL Developer и которую я не использовал, когда я пробовал провайдера Microsoft), всегда выполняла следующие операторы, прежде чем что-либо делать:

ALTER SESSION SET NLS_COMP = LINGUISTIC
ALTER SESSION SET NLS_SORT = BINARY_CI

Они делают Oracle без учета регистра.Но они также делают все обычные индексы бесполезными.Поскольку мы выполняли запросы из представления, в него встроено упорядочение. А поскольку мы не являемся владельцем базы данных, мы не можем сделать индексы лингвистическими для решения проблемы производительности.

Предоставление способа не выполнятьэти утверждения в этом (редком) сценарии устранили проблему.

4 голосов
/ 07 сентября 2010

Непосредственные мысли

  1. CLOB, BLOB или LONG / LONG RAW, которые требуют большой полосы пропускания всего для нескольких строк.
  2. Неверные данные (например, есть способы получить недопустимую дату в поле даты, что может сбить некоторых клиентов с толку)
  3. "the_table" на самом деле не таблица, а представление или что-то со сложным производным или имеет политику безопасности VPD / RLS / FGAC.
  4. Экзотический тип данных (пространственный или пользовательский).

Предложения

  1. Явно перечислите столбцы (например, SELECT a, b, c FROM the_table WHERE ROWNUM <5). Добавляйте столбцы один за другим, пока он не перестанет работать. Это предполагает, что в таблице есть хотя бы один «простой» столбец. </li>
  2. Проверьте сеанс в v $ session, чтобы увидеть, что такое EVENT ожидания. Либо сервер БД использует ЦП для этого SQL, либо он чего-то ждет (возможно, клиент).
  3. Проверьте SQL в v $ sql. Есть ли один или несколько дочерних курсоров. есть один или несколько PLAN_HASH_VALUE. Разные дочерние курсоры могут использовать разные планы. Без предложения WHERE, кроме ROWNUM, это маловероятно.
2 голосов
/ 08 сентября 2010

Представление добавляет разную степень сложности.«Столбец ВЫБРАТЬ ИЗ таблицы, ГДЕ rownum <5», вероятно, имеет только один план объяснения, выбирая данные из одного локального объекта. </p>

Для представления вы должны начать с получения текста представления SELECT TEXT FROM ALL_VIEWS WHERE VIEW_NAME = ...

Существует много различий между сеансами ODP.NET и SQL Developer.Я бы подумал о параметрах NLS (таких как форматы даты) и настройках набора символов.

Если вы можете найти SQL в v $ sql, вы можете сделать DBMS_XPLAN.DISPLAY_CURSOR (sql_id), чтобы посмотреть на разныепланы и посмотреть, если вы можете определить проблему.

0 голосов
/ 08 сентября 2010

В проекте, над которым я работал у моего бывшего работодателя, мы использовали odp.net для связи с большой базой данных системы розничной торговли, и мы получали ошибки при потере соединения.

Потребовалось много усилий, чтобы доказать, но в итоге он оказался поврежденным индексом в базе данных Oracle, который был затронут только нашим запросом.Администратор базы данных в конечном итоге проследил это до coredump процесса, который выполнялся на Sun box, когда выполнялся наш запрос.Мы не использовали какие-либо подсказки и т. Д., Но когда мы выполняли тот же запрос в Toad, он не попал в этот конкретный индекс.странно ?? << </p>

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