When using Hibernate as a ORM solution, it is natural to fall into a sense of ease with the tool and what it can do. However, once you begin to load data into your application, there are several performance gaps that will quickly become apparent. One of these gaps is the absence of indexes on the parent foreign key column in the child table.
When you create a
association in Hibernate, the child table (the many) holds a foreign key to the parent table (the one). When a call is made in Java to
parent.getChildren(), Hibernate will execute the query equivalent to:
select * from child where parent_id = ?. With the absence of the index, the database will be forced to perform a full table scan to load the children. With an index, the database can simply use the index to perform an optimized fetch of the child records.
To create an index on each foreign key in the application’s domain tables would be quite tedious; as I encountered. To add the indexes quickly, I wrote the following PL/SQL routine that can be run on the database (I am using Oracle). The function will iterate over all tables except for the
JOIN tables and create an index on each foreign key column.
After creating the indexes, the performance of your application should be quite noticeable, especially for the parents that have large collections of children.
Obviously any additional tables that should be excluded from this function would be added by modifying the
SELECT statement that loads the foreign key constraints into the cursor in the
DECLARE section of the PL/SQL block.
You can download the PL/SQL function here: fk_index_builder.sql