How to speed up the process of updating / inserting an Oracle application through Java?

I had a problem in my company: our program speed is not fast enough. To be more specific, we are a telecommunications company, and this program processes a call / surfing transaction made by all mobile phone users in our city. Since the amount of downloadable content made by iphone users is too large, our program cannot handle them fast enough.

The situation is that the amount of transactions made by users doubles the transaction processed by our program. In most cases, runtime programs are dominated by DB transactions.

I searched the Internet and looked at some sites (for example: http://www.javaperformancetuning.com/tips/rawtips.shtml ) talking about Java performace in the database, but I can not find a suggestion suitable for us.

These tips are not applicable / are already used, for example:

1. Use prepared statements. Use parameterized SQL

A trained operator has already been used. Each time a different parameter will be used by clearing the parameters and setting the parameters.

2. Configure SQL to minimize returned data (for example, not "SELECT *").

Of course, already in use.

3. Use the connection pool.

We make one connection at runtime. And I doubt that the union cannot solve the problem, because our program acts as 1 user, so there are no problems for simultaneous access to the database. If any of you think the pool is good, please tell me why. Thanks.

4. Try combining queries and batch updates.

Impossible to do this. Each request / insert / update depends on the database information. For example, we look at the database for information about the client, if we cannot find its use, we insert this use into the database, otherwise we are updated.

5. Close the resources (Connections, Statementments, ResultSets) upon completion

Of course.

6. Select the fastest JDBC driver.

I dont know. I am searching on the Internet about the type of drivers available, and I am very confused. We use oracle.jdbc.driver.OracleDriver , and we use thin instead of oci, which is all I know. In addition, our two-level program (java ↔ oracle)

7. Disable auto-commit

already done that.

Seek any help ahead.

+6
java database oracle
source share
7 answers

Get a copy of Oracle Professional Programming .

In 2005, this looks like the old side, but Oracle doesn't change much when it comes to performance optimization. I have this book and I used it to speed up the seemingly intractable performance problems for many applications. Take it. Read. Do it.

So what can you do while waiting for express delivery?

  • Get a DBA by your side, you will need their help and their tools.
  • Purchase TOAD and, if necessary, pay for additional query analysis tools
  • Check your indexes for each query you run - you need to carefully study the execution plans (your AUTOTRACE and EXPLAIN PLAN are used here).
  • Consider the type of index you are using (can a functional index do the trick?)
  • Consider using portable table spaces
  • Use the built-in optimizer to collect information
  • Get statistics so you can measure performance gains (regardless of pre-caching, etc.)
  • Consider saved contours
  • Consider materialized views to allow sharing of your data into what is needed immediately and what might delay the delay.
  • Consider truncating tables to reduce the size of shared tables as old data is deleted.

This should be enough to give you a solid understanding of what is failing and how to fix it.

+4
source share

4. Try combining queries and batch updates.

Impossible to do this. Each request / insert / update depends on the database information. For example, we look at the database for information, if we cannot find its use, we insert the use into the database, otherwise we are updated.

If you do this from a Java application, you can improve performance by doing this in the database in one round. There are several ways:

1) Use the SQL MERGE statement

2) Write a stored procedure for the insert or update logic and just call it from Java.

Further explanation

I assume from what you said that at the moment you have Java logic that works as follows:

 // Pseudocode execute SQL 'select count(*) from mytable where id=?' if result = 0 then execute SQL 'insert into mytable (id,a,b,c) values (?,?,?,?)'; else execute SQL 'update mytable set a=?, b=?, c=? where id=?'; end if; 

This means that there are two separate routes to the database: one to check for a record, and the other to insert or update as needed.

Alternatives:

1) Use the SQL MERGE statement:

 // Pseudocode execute SQL 'merge into mytable t using (select ? id, ? a, ? b, ? c from dual) s on (t.id = s.id) when matched then update set ta = sa, tb = sb, tc = sc when not matched then insert (id, a, b, c) values (s.id, sa, sb, sc)'; 

The MERGE operation is a bit complicated at first, especially when you need to use an Oracle “dual” table.

2) Use the stored procedure:

 // Pseudocode execute SQL 'begin mytable_package.insert_or_update (p_id => ?, p_a => ?, p_b => ?, p_c => ?); end;' 

The stored procedure in the mytable_package package will look something like this:

 procedure insert_or_update (p_id mytable.id%type ,p_a mytable.a%type ,p_b mytable.a%type ,p_c mytable.a%type ) is begin update mytable set a = p_a, b = p_b, c = p_c where id = p_id; if sql%rowcount = 0 then insert into mytable (id, a, b, c) values (p_id, p_a, p_b, p_c); end if; end; 
+10
source share

Check your indexes !!! Poor update performance may result from a foreign key constraint in which the index in the foreign key is not in the link table.

4) Try combining the requests and the service pack.

Impossible to do this. Each request / insert / update depends on the database information. For example, we look at the database for information, if we cannot find its use, we insert the use into the database, otherwise we are updated.

Two things come to my mind:

  • Make an UPDATE statement and check the result of ExecuteUpdate (); only if it is zero, enter INSERT. Saves one SELECT statement.

  • Always (possibly batch) insert into the staging table, then use MERGE to update your usage table.

5) Close resources (connections, statements, ResultSets) upon completion

Keep the connection open for as long as possible (i.e., forever until the server shuts down), prepare PreparedStatement once, and reuse it.


Make a few aggregates before writing to the database. Now the user of the cell phone that generates the transaction is likely to generate another one in a few seconds. Use a hash table to aggregate current usage and write to the database in a minute or so.

+6
source share

First of all, you need a database administrator on your side to tell you where the time is actually spent. You can be fast, like lightning in your client, and have long transactions until a critical index is configured.

Eight years have passed since I worked with Java + Oracle, but then I did not find the oci driver (using my own driver in the DLL) much faster than the thin driver then (everything is written in Java).

Quick work to give you room for breathing may be to create a text file with 1000 or 10,000 transactions at a time and let SQLLDR insert the package into the database. Perhaps even more. Properly invoked SQLLDR is the fastest thing, and it will buy you time to do it right.

+3
source share

Are you launching new JVM instances for each run? Can you tell us in detail about the nature of your application (for example, how it is called, what causes a call to start, etc.). From your description, this does not seem to be a problem with Java and DB. It looks like maybe some kind of problem with the database index or another design problem. What is the nature of the SQL commands you use? Have you timed or profiled these calls to find out if some of them accept more than others?

0
source share

Is it possible to split the workload by using multiple sessions in the database? There are many latency rides in the database. If your tables are structured correctly, they can handle multiple parallel inserts / updates without problems (check the INITRANS property for heavy inserted tables in the same way as the number of parallel sessions that perform the insert). I think this will be the easiest way to win performance for your application. What version of the database is used? Can you get ADDM reports? They can immediately tell you that - if any - the problem is in the database. Does the application server have enough processor resources? If not, this is another reason to divide the load into several sessions, in this case divided into several application servers. Without a statistics report or — preferably — an ADDM report, it is difficult to determine where the problem is.

Hope this helps, Ronald.

0
source share

If you want DBA to be minimal, you could at least ask for a login to access Oracle Enterprise Manager running on a test server. In OEM, you can see which operations take a lot of time. OEM will also try to help you by suggesting ways to improve performance, such as adding indexes or changing the structure of your queries. We hope that OEM can at least give you good reason to request further involvement from database administrators.

0
source share

All Articles