Showing posts with label adf performance related issue. Show all posts
Showing posts with label adf performance related issue. Show all posts

Wednesday, 25 December 2019

Performance issues in oracle ADF. How to detect performance issues in ADF Applications?

Oracle ADF is a very exhaustive framework that provides so many inbuilt functionalities to ease the work of the developer and help the developer in building applications quickly. ADF was built to support large Enterprise level Applications. But with so many functionalities sometimes due to large data or improper implementation of certain business functions, comes the issues related to the performance of the Applications.

ADF is fast!! If your ADF Application is slow, that eventually is due to development mistakes.

This blog post is related to ADF Performance issues that we face in applications. The most important challenge is to identify the exact issue and resolve that issue. Here are a few issues which I have found out during development as ADF Developer.

Reasons for performance issues in Oracle ADF applications

1. Long-running view object Query.


This can be the main reason for the slow performance of the ADF application. First, the Query needs to be identified which is causing the problem. How to identify the query?? I have posted a very detailed answer in this post. The performance-related issue in oracle ADF? How to Identify long-running queries of View Object?

2. ViewObject loading a huge number of records in the memory. 

This happening mostly due to the unintentional loading of huge no. of rows in the memory. How to identify the root cause. In this post, I have looked into this issue in detail. ADF ViewObject loading a huge number of records in the memory? Why? How this can be stopped?

3. Repeated execution of view accessors.

View accessors are the source for a Lov in a view object. There is a property that defines if the view accessor will be executed for all the rows in the view object or not. If the LOV values will remain the same for all the rows of the view object then this needs to set false. In the other case, this needs to be set to false.

view accessor row level bind variable in adf

4. Repeated execution of database functions in attribute getters in rowImpl classes.

The getters are called every time a value is called. The getters are called each and every time a values is called and if some calculating logic is written then it will be called many times which will eventually reduce the performance of the application.

5. Slow running database call, like database function or procedure, etc.

A database function or procedure that is being called is not optimized and taking much time to execute. If this is the case then optimization needs to be done at database level.

6. Unintentional use of "ignore case" clause in view criteria.

Ignore case is used to ignore the case of values in where clause. When we use the upper clause the sql query is like 

 ( (UPPER(Employees.FIRST_NAME) = UPPER(:bindFirstNm) ) ) 

 as we know that the upper clause is slower than normal where clause. Sometimes if this is used unintentionally this can be a cause for the slow query.

ignore clause in view object

7. Improper use of LOV type.

There are so many different types of LOV's in ADF and each has a different purpose. If the LOV is used properly for the business scenario for which it is applicable, then it can lead to different issues which can be problematic. For Example, if we use single selection LOV for a Larg no. of records then it can cause the Application to load slow. I have a detailed post where I have explained this in detail. What happens when we use the wrong type of a LOV??
 

8. Improper view object tuning.

View Objects are used to fetch records from the database. View objects by default tuned for optimal usage. But in some business cases if we are required to play with a large no. of rows of a view object. So the rows need to be loaded in the memory intentionally. In this case, we can use view object tuning to fetch the rows into memory in minimum time. This is not one fit for all solutions. But this will work well. We have some tuning parameters of view object defined in view object tuning section of a view object. 

view object tuning parameters image

I have discussed these parameters in detail in an old post of mine. https://adfjavacodes.blogspot.com/2014/04/adf-scrolling-in-table-with-large-data.html

9. Improper implementation of a use case.

This is the obvious reason in most for the performance-related issues in ADF. This case is best explained in the blog of Andrej https://andrejusb.blogspot.com/2017/11/adf-performance-story-this-time.html



If you have any queries related to the above blog post, please feel free to ask. :)

Tuesday, 17 December 2019

ADF ViewObject loading a huge number of records in the memory? Why? How this can be stopped?

View object loading an unnecessary no. of rows in the memory can be a strong reason for causing performance-related issues in oracle ADF applications. There are many scenarios where the rows are being loaded in the memory unintentionally. As too many rows are loaded into the memory this will lead to slow application performance.

There can be many reasons due to which this is happing.

1. The wrong List of Values used.

        a. There are several types of LOV's that are defined in ADF.
        b. Each has different usage depending on the use case.
        c. To explain the point above I will only talk about two, i.e. af:InputListofValues (Lens Lov) and af:selectOneChoice (Dropdown LOV).
        d. af:InputListofValues(Lens LOV): These LOV's are used where the user has to select a value from a very large no. of options. Users can narrow down the list by search and filter and then select the record. This type of LOV loads a small no. of rows (Max 10 Default Query Limit) in the system List of Values Properties in the ViewObject.

ADF af:InputListOfValues

       
        e. af:selectOneChoice (Dropdown LOV): These LOV's are used where the user has to select the value from a small no. of Options lets say 5 to 10. In this case, all the records are displayed on the page and there is not Query Limit by Default.

ADF Single Selection LOV

        f. So if during the implementation if in case if no. of values is large and single selection Lov is used then a large no. of rows will be loaded in the memory and will lead to slow application loading.

        

2. Range of Table set to -1 which means all the rows that are loaded from view object query.


The default range of a view object if dropped on the Page is 25 that means 25 rows will be loaded into memory if that view Object is page is rendered. If the range size is changed to  -1 than all the rows in the view object will be loaded in the memory on the first request and if there are large no. of rows returned from the view object Query then it will take time to load. As per my experience, it is never advised to set the range size of a table to -1.    


oracle ADF Table


3. Use of getFilteredRows or RowQualifier for in-memory filtration in the Application.

        a. getFilteredRows or RowQualifier are used for filtering the rows of the view object programmatically.
        b. These are in-memory filtration, i.e. first all the rows will be loaded in the memory and then filtration will be done.
        c. But this filtration is done in the memory, and if the is being done on a view object which has a large no. of rows then all the rows will be first loaded into the memory which will lead to slow application processing.


How to identify the view object which is loading huge no. of Rows.

ADF shows all the model layer activities using oracle.jbo logger and by setting it to finest we can see minute details of the processes that are being executed when the application is running.
How to enable the logger? I have mentioned the steps to enable the logger in this post ->
Performance-related issues in oracle ADF? How to Identify long-running queries of View Object?

Now run the application and open the logger window and while application is loading see the log. It will show the queries which are being executed. If the log is stuck at some query and the log shows something like this.


The line "$$added root$$ id=-2" means that the Application is loading all the rows of the view object of the above query. 


Solution.

1. First identify the view object or Lov which is loading large no. of rows.
2. Check the references of the view object, where they are used and how they are used.
3. Check if the view object is used for in-memory filtration or not. If yes, then check how many rows are being loaded into memory and why they are being loaded in the memory. Maybe there is any issue in implementation logic due to which this is happening.

 
If you have any questions or queries related to the above blog, please feel free to ask. :)