Friday, November 10, 2017

ADF Performance Story - This Time Developer Was Wrong

ADF is fast. If ADF application is slow, most likely this is related to development mistakes. I would like to tell you one story, based on my ADF tuning experience. Problem description: ADF application runs fast in DEV, when DB size is small. Same application runs slow in TEST/PROD, when DB size is large. Question - what is slow. Answer - slow means forms are loading slow. Ok, lets go to the story.

Developer decides to fetch data from DB and iterate over rows to process them. This is already bad practice, because it is much more effective to process large sets of rows in DB directly, without fetching to middle tier. But let's assume this is valid use case and we really need to fetch rows. Developer implements fetching using getAllRowsInRange method:

VO data is loaded on UI and displayed in the table. Method to iterate through rows is called from button, this logic is not executed on initial load. Iterator is set with Range Size = 10:

This means first 10 rows are fetched on form load and it will open fast no matter of DB size:

This is OK, but while testing row fetching functionality - developer finds a "bug". He will see that instead of fetching all rows in custom method, only 10 rows are returned. And then developer decides to implement a fix - change Range Size to -1:

Now all rows are fetched in custom method, developer is happy. But there is small side effect - for some reason table starts to display all rows. Not good, another fix is needed:

Auto Height Rows = 10 is set to prevent table displaying too many rows. But really still all rows will be fetched, because Range Size = -1:

All these fixes are wrong. Method getAllRowsInRange is not supposed to be used to iterate through all rows, it will return only currently fetched rows. Such implementation obviously will slow down form load functionality, it will fetch all rows from DB, if DB size is large - it will slow down significantly.

If all what you need is to iterate through rows, make sure you dont affect data which is displayed/fetched for UI. Keep Range Size positive:

In custom method iterate through rows by creating rowset iterator:

Download sample application -