Pull to refresh

Comments 35

А проводили сравнение с Managed ODP?
Как раз Managed.ODP и использовался…
Managed ODP.NET пока не поддерживается на Mono. По скорости тесты не гоняли. У DevArt есть проблемы совместимости (уже плохо помню, но кажется с блобами какие-то косяки были) и распределенными транзакциями.
Мы думали использовать его, по полезли баги и отказались. В случае с ораклом производительность провайдера скорее последнее что будет тормозить :)
Что то в статье не увидел где указано, что речь идет о Mono. Кстати, если речь идет о Mono, то под какой операционной системой проводилось тестирование?
Нигде, в статье указано, что если требуется переносимость. Managed ODP не совсем такой ибо нет Mono.
Наверное я не совсем корректно выразился, т.к. под переносимостью имел ввиду легкое разворачивание софта на клиентской машине.
А в чем преимущество в переносимости тогда перед DevArt? Для Managed ODP надо таскать одну библиотеку, котороую просто можно включить в дистрибутив (в некоторых случаях — две или три если с разной архитектурой:
Oracle.DataAccess.dll
Oracle.ManagedDataAccess.dll
Oracle.ManagedDataAccessDTC.dll
Для ODP ещё нужен установленный клиент Oracle как минимум. В случае dotConnect Direct Mode нужна пара его библиотек и oci8.dll
Для Managed не нужен.
А при пакетной вставке использовался один раз подготовленный стейтмент, и много раз привязанные переменные?
Нет. Парсится в каждой итерации цикла и хуже того, в каждой итерации комитится.
Посмотрите на GitHub. В общем, странное тестирование.
Потому что тестировался процесс обработки некой транзакции, которую нужно атомарно сохранить в БД, закоммитить, забыть и заниматься следующей.
Только вот получилось, что меряли вы не скорость вставки, а сплошные накладные расходы.
Так в этом и был основной замысел: сравнить накладные расходы двух провайдеров при выполнении аналогичных операций с БД.
Если мерять скорость вставки, то проще уж запустить скрипт в sqlplus…
Так то оно так, но вы меряете накладные расходы самого Oracle.
Накладные расходы любых провайдеров (честно выполняющих синхронный commit) просто меркнут на их фоне.
А без коммита мы будем тестировать хватает ли undo. В любом случае мне нужно было оценить свою ситуацию, а не некую абстракцию.
Ну, в Oracle теперь есть асинхронный commit. О его достоинствах можно спорить, но, как минимум, вы не будете его мерять в тесте. Если же по старинке, то можно коммитить, по несколько записей (100-1000) и вынести commit за пределы замера времени.
Я понял вашу мысль, но тогда получится тест ради теста. Моё же тестирование чисто практическое для конкретной задачи.
Вообще в реальной системе на каждой итерации происходит следующее: открывается новое соединение, выполняется кучка select/insert, commit/rollback по ситуации (синхронный, естественно), после чего соединение закрывается.

Ради интереса на досуге запущу с единым коммитом в конце, хотя сомневаюсь что это резко изменит результаты.

PS: Если честно, то я довольно давно использую OraDirect/dotConnect и был в нём всегда уверен. Поэтому сам несколько обескуражен результатами.
Поверьте мне, построчный commit изменяет результат так, что все прочие биндинги и префетчи плачут кровавыми слезами. Для производительности самого приложения это тоже может быть очень актуально. РСУБД хорошо работают с массовыми операциями, построчная обработка — это не про них.
Про построчные коммиты очень хорошо знаю. В тесте ведь нет речи про commit после каждой записи, транзакция завершается после выполнения последовательность DML-команд (итерации).

PS: Но спасибо вам за эту цепочку, потому что выключая commit'ы и увидел непростительную ошибку копипасты — при тестировании ODP.NET всё идёт в рамках одной транзакции, в отличие от dotConnect.
После повторного тестирования возможно всё преимущество ODP.NET испарится… Обновлю публикацию в ближайшее время (и, скорее всего, придется посыпать голову пеплом).
Стeйтмент готовился на каждой итерации (потому что тестирование приближали к тому, что потребуется нам), но на выходе был один и тот же PL/SQL блок вида:
begin
  insert into t1 (c1, c2, ...) values (:v1, :v2, ...);
  insert into t2 (c1, c2, ...) values (:v1, :v2, ...);
  ...
end;

А использование bind-переменных в OLTP — это закон.
Биндинг переменных — это хорошо (в большинстве случаев). Спасает от жёстких разборов.
А как быть с мягкими?
Как минимум использовать stored proc… :)

Если же вы намекаете на повторное использование заранее приготовленного OracleCommand, то, да — можно убрать soft parse в самом первом тесте со многими insert. В остальных случаях не получится, т.к. в моей реальности я имею дело с новым соединением для каждой транзакции.
Это аргумент. Но мы у себя с ним справились.
Элементарно. Сохраняем разобранный запрос в каждой сессии где он засветился.
Пул сессий наш. Всё на Java.
Во, «свой connection pool» — это ключевое. Я думал, что есть некие стандартные средства…
Да, пользовались им для кэширования тяжелых функций, но это вещь в себе — неявный сброс кеша и latch free events возникают в самый неподходящий момент. Поэтому, кстати, было довольно трудно оценить реальный прирост производительности при его использовании.
Включите пожалуйста в сравнение insert с помощью array-binding.
Спасибо за идею!
В array-binding dotConnect и ODP.NET выступили практически на равных (dotConnect на на незначительные 4% медленнее).

Получается что если используется решение от DevArt, то array-binding в два раза производительнее хранимых процедур. В случае ODP.NET — на 36% медленнее. Итоговый вывод о том, что ODP.NET + stored proc = высокая производительность остаётся в силе.
Оригинально. У нас array binding всегда побеждает. С большим отрывом.
Oracle 12c
У всех разные условия. Возможно, у вас немного смещены акценты на то, что нужно именно вам.

В любом случае, что array binding, что stored proc показали себя хорошо. Первый. конечно, поддерживать гораздо проще…
Секрет, я полагаю, вот в этом — Parameter.Size = 8;
Мы, к примеру сотнями и тысячами вставляли за раз.
Sign up to leave a comment.

Articles