Oracle Thin JDBC Driver tuning

March 10, 2010

Oracle Thin JDBC Driver tuning

[ru] [en]

Some aspects of the Oracle Thin JDBC Driver usage in a database with big quantity of varchar columns or "Hello, REAL World".

[ page 1 ][ page 2 ][ page 3 ][ page 4 ]

За все время работы ни разу не слыхал о случаях какой-либо настройки Oracle Thin JDBC Driver. Он всегда используется "as is" и мало кому может вообще прийти в голову, что, возможно, именно он является тонким местом вашего приложения. Но это вполне может оказаться так.

Многие знают, что Oracle настоятельно рекомендует использовать jdbc последней (11g) версии даже для коннекта к 10 и 9-й версиям сервера. Немногие задаются вопросом "Почему". И зря. Именно в 11g версии они задекларировали существенное увеличение производительности и также добавили наконец механизмы настройки кэшей на уровне jdbc драйвра, что и предлагают настраивать самостоятельно в зависимости от режима использования. При этом в документации этот механизм кэширования назван настолько удачным, что заявлена большая производительность thin-драйвера перед OCI-драйвером (и в принципе рекомендуется переходить с oci на thin, поскольку его использование само по себе проще, да и производительность такая-же, если не лучше!)

>>> ... As of 10.1.0, the Thin driver is probably slightly faster than the OCI driver. ... <<<
Однако, не все так радужно, хотя, говоря по правде, oracle не очень кривит душой - ибо было еще хуже.

Вам повезло, если вы пишите "идеальное" приложение, где четкая модель данных, 3-я нормальная форма и аналитики абсолютно точно указали максимальные длины строковых полей. В реальной жизни вы встречаетесь с унаследованной структурой, часто специально де-нормализированной. Обмен csv-файлами остается, как это ни печально, если не основным, то существенным форматом интеграционного обмена в банковских и платежных системах (в таком виде, например, я видел не всегда захешированные номера кредиток, что высылались обычным SMTP от одной системы бухгалтерам другой, что после вручную импортировали эти данные для проведения сверки транзакций!). Часто это является следствием закрытости программных комплексов - выгрузка данных в csv из них является чуть ли ни единственной возможностью. В подобных случаях приходится в своей системе делать загрузочные таблицы, что состоят из сотен текстовых столбцов для хранения плоских записей информационного обмена. А однажды я рефакторил COBOL-овскую систему, в которой каждое новое состояние заказа сохранялось - где бы вы думали? - правильно, в новой группе столбцов таблицы! Там было ровно 1000 столбцов! И если вы узнаете в этом описании что-то из вашего проекта - эта статья для вас.

Имеем таблицу со 250 колонками nvarchar2(2000). Имеем некую процедуру - "Cleaner" - который блоками выбирает содержимое этих колонок на обработку, причем, на самом деле, данные содержаться только в первых 30-ти колонках - остальные не используются. Если указать в параметрах Cleaner-а выбирать из базы и анализировать только первые 50 столбиков, то получаем вот такой лог исполнения

...
20:59:59,016 INFO impl.Clean - Cleaner started in batch mode
21:00:00,243 INFO impl.Clean - 10 records cleaned
21:00:00,471 INFO impl.Clean - Cleaner started in batch mode
21:00:01,830 INFO impl.Clean - 10 records cleaned
21:00:01,864 INFO impl.Clean - Cleaner started in batch mode
21:00:03,005 INFO impl.Clean - 10 records cleaned
21:00:03,069 INFO impl.Clean - Cleaner started in batch mode
...
Если же сказать Cleaner-у выбирать из базы 100 колонок, то получаем вот такой лог
21:39:22,029 INFO impl.Clean - Cleaner started in batch mode
21:40:52,596 INFO impl.Clean - 10 records cleaned
21:42:28,825 INFO impl.Clean - Cleaner started in batch mode
21:42:31,744 INFO impl.Clean - 10 records cleaned
Сравните время, что потребовалось на выбор из базы 50 дополнительных пустых колонок. И кроме того - это полный лог. Ровно две итерации. Дальше - OutOfMemoryException.
For all the time I never heard about any cases of adjustment of the Oracle Thin JDBC Driver. It always used "as is" and few people can in general suggest that it is probably a bottleneck for your application. But it may be truth.

Exactly in the 11g version Oracle has declared a significant increase in performance and has added a way to adjust caches of the jdbc driver. Now you can configure it for yourself in depends of usage type. The caching mechanism is named so successful that the total performance of the Thin-driver becomes even better than OCI-driver (it's recommended to switch from OCI to Thin, because it more simple, and has a better performance!)

>>> ... As of 10.1.0, the Thin driver is probably slightly faster than the OCI driver. ... <<<
However all is not so rosy, but telling the truth Oracle not really meant it - it was even worse.

You're lucky if you work with a "perfect" project, where data model is normalized and analysts have pointed out exactly the maximum length of string fields. In real life you meet with the legacy structures (often specially de-normalized). The CSV-format still remains maybe not the main but essential for the data exchange and integration in banking and payment systems ( I saw it for example in such regular process when not always hashed credit card numbers that were processed by an ordinary SMTP from one system to the accountants of another and than were manually imported into payment system to perform reconciliation of transactions!). Often it is a result of usage of proprietary closed software when CSV is exactly one ability to export data. In such cases you are forced to create a input-tables in your system that consists of a number of string columns. And once I was involved into refactoring of a COBOL system where each new state of an entity-object was persistent into - what do you think? - into the new group of columns in the same table! Such table kept exactly 1000 columns! And if you find something from your project in this description - this article is for you.

I have a table with 250 of nvarchar2(2000) columns and I have a certain procedure (call it "Cleaner") which selects the contents of these columns for processing (and in fact the data is contained only in the first 30 columns - the others are not used yet but “may be” be used later). In a case when I specify in the Cleaner's parameters to select and analyze from the database only the first 50 columns I get such execution log:

...
20:59:59,016 INFO impl.Clean - Cleaner started in batch mode
21:00:00,243 INFO impl.Clean - 10 records cleaned
21:00:00,471 INFO impl.Clean - Cleaner started in batch mode
21:00:01,830 INFO impl.Clean - 10 records cleaned
21:00:01,864 INFO impl.Clean - Cleaner started in batch mode
21:00:03,005 INFO impl.Clean - 10 records cleaned
21:00:03,069 INFO impl.Clean - Cleaner started in batch mode
...
However if to configure the Cleaner to select 100 columns from the table then the log is
21:39:22,029 INFO impl.Clean - Cleaner started in batch mode
21:40:52,596 INFO impl.Clean - 10 records cleaned
21:42:28,825 INFO impl.Clean - Cleaner started in batch mode
21:42:31,744 INFO impl.Clean - 10 records cleaned
Please, just take a look on a time that was used to select 50 additional emply columns. And, by the way, this is a full log. Two iterations exactly. After that the OutOfMemoryException.

To be continued ... >>>

0 comments:

Post a Comment