8.8 Best Practices for Oracle RDF Graph Adapter for Eclipse RDF4J

This section explains the performance best practices for Oracle RDF Graph Adapter for Eclipse RDF4J.

Closing Resources

Application programmers should take care to avoid resource leaks. For Oracle RDF Graph Adapter for Eclipse RDF4J, the two most important types of resource leaks to prevent are JDBC connection leaks and database cursor leaks.

Preventing JDBC Connection Leaks

A new JDBC connection is obtained from the OraclePool every time you call getConnection on an OracleRepository or OracleSailStore to create an OracleSailConnection or OracleSailRepositoryConnection object. You must ensure that these JDBC connections are returned to the OraclePool by explicitly calling the close method on the OracleSailConnection or OracleSailRepositoryConnection objects that you create.

Preventing Database Cursor Leaks

Several RDF4J API calls return an Iterator. When using the adapter for Eclipse RDF4J, many of these iterators have underlying JDBC ResultSets that are opened when the iterator is created and therefore must be closed to prevent database cursor leaks.

Oracle’s iterators can be closed in two ways:

  1. By creating them in try-with-resources statements and relying on Java Autoclosable to close the iterator.
    
    String queryString = 
       "PREFIX ex: <http://example.org/ontology/>\n"+
       "SELECT * WHERE {?x ex:name ?y}\n" +
       "ORDER BY ASC(STR(?y)) LIMIT 1 ";
    
    TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
    
    try (TupleQueryResult result = tupleQuery.evaluate()) {
      while (result.hasNext()) {
        BindingSet bindingSet = result.next();
        System.out.println("value of x: " + bindingSet.getValue("x"));
        System.out..println("value of y: " + bindingSet.getValue("y"))
      }
    }
  2. By explicitly calling the close method on the iterator.
    
    String queryString =
      "PREFIX ex: <http://example.org/ontology/>\n"+
      "SELECT * WHERE {?x ex:name ?y}\n" +        
      "ORDER BY ASC(STR(?y)) LIMIT 1 ";      
    TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString);      
    TupleQueryResult result = tupleQuery.evaluate();      
    try {        
      while (result.hasNext()) {          
        BindingSet bindingSet = result.next();          
        System.out.println("value of x: " + bindingSet.getValue("x"));          
        System.out..println("value of y: " + bindingSet.getValue("y"))        
      }      
    }      
    finally {        
      result.close();      
    }

Gathering Statistics

It is strongly recommended that you analyze the application table, RDF graph, and inferred graph in case it exists before performing inference and after loading a significant amount of RDF data into the database. Performing the analysis operations causes statistics to be gathered, which will help the Oracle optimizer select efficient execution plans when answering queries.

To gather relevant statistics, you can use the following methods in the OracleSailConnection:

  • OracleSailConnection.analyze
  • OracleSailConnection.analyzeApplicationTable

For information about these methods, including their parameters, see the RDF Graph Support for Eclipse RDF4J Javadoc.

JDBC Bind Values

It is strongly recommended that you use JDBC bind values whenever you execute a series of SPARQL queries that differ only in constant values. Using bind values saves significant query compilation overhead and can lead to much higher throughput for your query workload.

For more information about JDBC bind values, see Using JDBC BIND Values and Example 13: Using JDBC Bind Values.