English version

При работе Xafari приложений на платформе Oracle c большим количеством данных было замечено снижение производительности по сравнению с тем же приложением, но работающим на платформе MS-SQL. Анализ данной проблемы показал, что при сложных запросах в БД не участвовали индексы, хотя эти индексы и присутствовали в БД. Более глубокая локализация выявила причину такого поведения.

Поля "Oid" большинства бизнес-классов имеют типа Guid. При маппинге бизнес-классов в базу данных Oracle эти поля будут иметь тип CHAR. В процессе работы приложения, возникают сложные параметризированные запросы с условиями, в которых передача параметров выполнялась с типом NVARCHAR2 к колонкам типа CHAR. Именно по этой причине и не подхватывались индексы, так как в таких запросах Oracle выполнял внутреннее преобразование из одного типа в другой.

Благодаря очень гибкой архитектуре Devexpress XAF, предоставляющей множество точек расширения, данную проблему удалось решить самостоятельно. Для решения разработали модуль Xafari.DB, в котором присутствовала реализация провайдеров для доступа к данным Oracle: XafariODPConnectionProvider и XafariOracleConnectionProvider. Данные классы являются, соответственно, наследниками от DevExpress классов ODPConnectionProvider и OracleConnectionProvider. В классах-провайдерах потребовалось переопределить метод CreateParameter() таким образом, чтобы для полей типа Guid передача параметров в запросах выполнялась с типом CHAR. Ниже представлен анализ полученных результатов в сравнении: без использования модуля Xafari.DB и с подключенным модулем Xafari.DB.

В целом благодаря Xafari.DB удалось ускорить выполнение сложных запросов в 40 и более раз.

Результаты тестирования на реальном приложении

Для тестирования было выбрано приложение на котором данная проблема проявлялась в наибольшей степени. Это приложение Галактика АММ.
Результаты представлены в таблице ниже:

SQL запросТаблицы участвующие в запросахВремя выполнения секунд

Ускорение
раз

ТаблицаКоличество записейбез Xafari.DBc Xafari.DB
№1ПозицияНормыРасхода79718822304847
НоменклатурнаяПозиция232534
ПозицияВедомостиМатериалов27515
Документ76
№2БазовыйТехнология2311603178359
ФайлБиблиотеки87
№3БазовыйТехнология2311603241640
НоменклатурнаяПозиция232`534
ФайлБиблиотеки87
Документ76
SQL запрос №1

SQL запрос №1 без использования модуля Xafari.DB имеет следующий план выполнения запроса:

Анализируя план выполнения запроса видно, что в нашем сложном запросе происходит полный перебор всех строк таблицы (TABLE ACCESS full). Метод доступа TABLE ACCESS full возникает в случае отсутствия индекса, либо по причинам того, что построенный индекс не подхватывается. В нашем же случае индекс присутствовал, но он не подхватывался по причине вызова внутренней функции Oracle SYS_OP_C2C. Данная функция выполняет преобразование одного типа к другому.

Теперь рассмотрим план выполнения запроса, но с подключенным модулем Xafari.DB:

С подключенным модулем Xafari.DB индекс подхватывается, запрос выполняется быстрее.

http://xafari.ru/wp-content/uploads/2014/09/3.jpg
Рис. 1 – Время выполнения SQL запроса №1 без модуля Xafari.DB http://xafari.ru/wp-content/uploads/2014/09/4.jpg
Рис. 2 – Время выполнения SQL запроса №1, но с модулем Xafari.DB

SQL запрос №2

SQL запрос №3