Почему метод загрузки данных иногда бывает таким медленным? - PullRequest
3 голосов
/ 27 июня 2011

Проект представляет собой веб-приложение на ASP / VB.net. Проблема заключается в том, что некоторые страницы являются невероятно медленными. После попытки найти узкое место было обнаружено, что это метод загрузки при заполнении таблицы данными с результатами запроса.

Мы используем базу данных Oracle, и запросы выполняются в хранимых процедурах. В качестве примера, у нас есть относительно простой оператор выбора в процедуре, который возвращает 2 столбца с 6 строками, для выполнения которых было определено, что это займет около 0,015 секунд. Однако загрузка OracleDataReader в таблицу данных занимает в среднем 7 секунд - смешное количество времени для такого небольшого набора записей. После того, как я возился с запросом, я обнаружил, что проблема возникает из-за простого оператора декодирования. Оператор декодирования используется следующим образом:

WHERE ДЕКОД (iBln, 1, столбец 1, столбец 2) МЕЖДУ iDate1 и iDate2

Переменная iBln - это просто число, передаваемое в качестве логической переменной для определения, какой столбец должен находиться между двумя датами. Если я закомментирую этот оператор декодирования и сделаю его просто «column1 BETWEEN iDate1 и iDate2», то метод загрузки вообще не займет время, как и должно быть, что означает, что это действительно оператор декодирования, вызывающий проблемы.

Так что я просто надеюсь услышать от кого-нибудь, кто мог бы иметь представление о том, что является причиной этого или как это исправить. Это простое декодирование, как оно вообще влияет на метод загрузки?

Ответы [ 2 ]

4 голосов
/ 27 июня 2011

Я бы проверил, существуют ли индексы для column1 и column2.Если это так, вероятная проблема заключается в том, что DECODE препятствует использованию индексов.Попробуйте переписать как:

WHERE ( ( iBin = 1 AND column1 BETWEEN iDate1 AND iDate2)
        OR
        ( (iBin IS NULL OR iBin <> 1) AND column2 BETWEEN iDate1 AND iDate2)
      )
3 голосов
/ 27 июня 2011

Если ваша хранимая процедура возвращает REF CURSOR, открытие курсора в хранимой процедуре будет очень быстрым независимо от того, какой запрос вы выполняете.Для открытия курсора не требуется, чтобы Oracle выполнял какую-либо работу по фактическому выполнению запроса, просто требуется, чтобы Oracle определил план запроса, который должен быть более или менее мгновенным.

Сколько времени занимает получениеданные из REF CURSOR в чем-то вроде SQL * Plus?Если это займет что-то около 7 секунд (как я подозреваю, это будет), вы можете исключить класс OracleDataReader как источник проблемы.В этом случае проблема почти наверняка заключается в том, что план запроса неэффективен.

Исходя из вашего описания, я предполагаю, что column1 проиндексирован.column2 тоже можно проиндексировать, не понятно.Но обычный индекс на column1 или column2 не может быть использован для оценки предиката, который включает вызов функции DECODE.Если в индексированных столбцах нет других предикатов, это может заставить Oracle выполнить сканирование таблицы в базовой таблице (было бы полезно опубликовать полный запрос, определение таблицы и план запроса).

...