Inside Scoop on J2EE : Tips and tricks on J2EE and Oracle Application Server by Debu Panda
Updated: 11/18/2004; 5:20:25 PM.

 

Subscribe to "Inside Scoop on J2EE" in Radio UserLand.

Click to see the XML version of this web page.

Click here to send an email to the editor of this weblog.

 
 

Friday, April 23, 2004

Tuning Database Access for CMP Entity beans

 

Database Administrators always claim the first step in tuning your

commercial applications is tune your SQL. However, tuning database

access for CMP entity beans are said easier than done! The first question

that springs to  every body’s mind ” SQL are generated by the EJB

container then how can I tune the SQL”. In this article I will describe how

you will go about tuning the database access by CMP entity beans. I will take Oracle database and OC4J as the example however this can be applied to any database and any J2EE containers.

 

The first step in tuning the database access is find the SQL statements

generated and executed by the container. You can find these SQL by

either increasing the debug level for your container or using a tool like

P6SPY (http://www.p6spy.com) to work in conjunction with your

container.

 

Following are few tips to tune database access for your CMP entity beans. Making good friendship with your DBA

always helps and he will teach the tips and tricks of his trade.

 

Make sure your finder/select methods use indexes

 

Index scan can dramatically improve the performance of SQL statements so make sure that the SQL statement generated by your finder uses an index instead of doing a full table scan.  For example, if you have a finder that finds your entities by name and you are trying to find an employee named Debu, apparently the SQL that your

EJB-QL will get translated will become like some thing:

 

select * from EMP where ename='Debu'

 

Make sure that your name column is indexed. You can use the EXPLAIN PLAN utility provided by Oracle to make sure that your query is using an INDEX SCAN.  These may be boring for you and you may seek your DBAs help.

 

You can setup SQL*Plus to automatically generate PLAN OF EXECUTION for your SQL statements at the end of execution with the following steps:

 

sqlplus scott/tiger

SQL> @$ORACLE_HOME/rdbms/admin/utlxplan.sql

SQL> set autotrace on

 

 

If you do not have an index on the ename column the plan of execution for your SQL statement and statistics your plan will look like:

 

Execution Plan

----------------------------------------------------------

   0      SELECT STATEMENT Optimizer=CHOOSE

   1    0   TABLE ACCESS (FULL) OF 'EMP' 

 

Statistics

----------------------------------------------------------

        131  recursive calls

          0  db block gets

         31  consistent gets

          0  physical reads

          0  redo size                                  

 

However if you have an index the Execution Plan and statistics will dramatically improve as follows:

 

Execution Plan

----------------------------------------------------------

   0      SELECT STATEMENT Optimizer=CHOOSE

   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'EMP'

   2    1     INDEX (RANGE SCAN) OF 'EMP_NAME_IDX' (NON-UNIQUE)

 

 

 

 

Statistics

----------------------------------------------------------

          0  recursive calls

          0  db block gets

          4  consistent gets

          0  physical reads

          0  redo size                                

 

 

 

 

 

Avoid findAll on entities based on large tables

 

When the findAll method is used, the container tries to retrieve all rows of the table on which the entity is based and thus a FULL TABLE SCAN occurs. Avoid using this method on entities based on large tables, as it will slow down your database.

 

Exploit statement caching

 

The Oracle database provides a feature that caches SQL statements. This reduces the parse time when the SQL statement is issued to the database multiple times. For example in OC4J you can enable statement parsing for your data-source by adding the statement-cache-size attribute:

 

<data-source>

...

stmt-cache-size="100"

</data-source>

 

 

Enforce primary key constraint at database level

 

Several EJB containers maintain the uniqueness of entity beans and do not rely on the existence of primary key constraints in the underlying database table. When a new bean is created, the container creates a new database record. Before writing this to the database, the container issues a SELECT statement to make sure the insert does not lead to a duplicate entry. Primary key constraints should be enforced at the database level, which avoids the extra SELECT statement.

 

For example, you can disable this extra constraint checking by OC4J by setting do-select-before-insert=”false” for your CMP entity bean.

 

 

Use DELETE CASCADE at database level

 

When an entity with relationships is deleted with multiplicity ONE, the container is responsible for deleting all dependent entities. The container generates and executes the required SQL code to remove all of the related child records from the database. Try to exploit the native cascade delete facility in the Oracle database; this avoids multiple delete statements when removing the dependent records and CASCADE DELETE in the database level is much faster. The database removes all related records when the CASCADE DELETE option is specified for the table. 

 

 

Set pre-fetch size to reduce roundtrips to the database

 

Oracle Database JDBC drivers have extensions that let you set the number of rows to pre-fetch to the client while a result set is being populated during a query. This reduces the number of roundtrips to the server, and can drastically improve the performance of finder methods that return a large number of rows.

 

You can set the pre-fetch size for your finder method in OC4J as follows in the vendor specific deployment descriptor:

 

<finder-method  query=”" prefetch-size="15" >

<!-- Generated SQL: "select * from EMP where EMP.ENAME = ?" -->

<method>

<ejb-name>EmployeeBean</ejb-name>

<method-name>findByName</method-name>

<method-params>

<method-param>java.lang.String</method-param>

</method-params>

</method>

</finder-method>

 

 

 

Define your own SQL Finder method

 

Several containers provide a way to define your own SQL for the finder method or an ability to override the SQL statement generated by your container. You have to use this in caution as this may have adverse effect on your application. You can write your highly optimized SQL statements for your finder method.

 

Conclusion

 

There are several other ways to improve the database access for your applications. You have carefully to examine the features offered by container to exploit these. Do not miss my JavaOne presentation this year where we will provide several tips and tricks to optimize CMP entity beans.

 


4:01:09 AM    comment []

© Copyright 2004 Debu Panda.

PS: These are my own thoughts and not of my employer ..



Click here to visit the Radio UserLand website.
 


April 2004
Sun Mon Tue Wed Thu Fri Sat
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30  
Mar   May