Tuning Derby
Version 10.4
Derby Document build:
May 15, 2008, 11:40:11 AM (PDT)




Version 10.4   Tuning Derby
   
Contents
Copyright    
License    
About this guide    
Purpose of this guide    
Audience    
How this guide is organized    
Working with Derby properties    
Properties overview    
Scope of properties    
Persistence of properties    
Precedence of properties    
Dynamic versus static properties    
Ways of setting Derby properties    
System-wide properties    
Database-wide properties    
In a client/server environment    
Dynamic or static changes to properties    
Properties case study    
Performance tips and tricks    
The tips    
Use prepared statements with substitution parameters    
Create indexes, and make sure they are being used    
Increase the size of the data page cache    
Tune the size of database pages    
Avoid expensive queries    
Use the appropriate getXXX and setXXX methods for the type    
Tune database booting/class loading    
Avoid inserts in autocommit mode if possible    
Customize the optimizer methods for table functions    
More tips    
Shut down the system properly    
Put Derby first in your classpath    
Tuning databases and applications    
Application and database design issues    
Avoiding table scans of large tables    
Avoiding compiling SQL statements    
Shielding users from Derby class-loading events    
Analyzing statement execution    
Working with RunTimeStatistics    
Overview    
How you use the RUNTIMESTATISTICS attribute    
Analyzing the information    
DML statements and performance    
Performance and optimization    
Index use and access paths    
Joins and performance    
Derby's cost-based optimization    
Locking and performance    
Transaction-based lock escalation    
Locking a table for the duration of a transaction    
Non-cost-based optimizations    
Non-cost-based sort avoidance (tuple filtering)    
The MIN() and MAX() optimizations    
Overriding the default optimizer behavior    
Selectivity and cardinality statistics    
Determinations of rows scanned from disk for a table scan    
How the optimizer determines the number of rows in a table    
Estimations of rows scanned from disk for an index scan    
Queries with a known search condition    
Queries with an unknown search condition    
Statistics-based versus hard-wired selectivity    
Selectivity from cardinality statistics    
Selectivity from hard-wired assumptions    
What are cardinality statistics?    
Working with cardinality statistics    
When cardinality statistics are automatically updated    
When cardinality statistics go stale    
Derby properties    
Scope of Derby properties    
Derby properties    
derby.authentication.ldap.searchAuthDN    
derby.authentication.ldap.searchAuthPW    
derby.authentication.ldap.searchBase    
derby.authentication.ldap.searchFilter    
derby.authentication.provider    
derby.authentication.server    
derby.connection.requireAuthentication    
derby.database.defaultConnectionMode    
derby.database.forceDatabaseLock    
derby.database.fullAccessUsers    
derby.database.noAutoBoot    
derby.database.propertiesOnly    
derby.database.readOnlyAccessUsers    
derby.database.sqlAuthorization    
derby.infolog.append    
derby.jdbc.xaTransactionTimeout    
derby.language.logQueryPlan    
derby.language.logStatementText    
derby.locks.deadlockTimeout    
derby.locks.deadlockTrace    
derby.locks.escalationThreshold    
derby.locks.monitor    
derby.locks.waitTimeout    
derby.replication.logBufferSize    
derby.replication.maxLogShippingInterval    
derby.replication.minLogShippingInterval    
derby.replication.verbose    
derby.storage.initialPages    
derby.storage.minimumRecordSize    
derby.storage.pageCacheSize    
derby.storage.pageReservedSpace    
derby.storage.pageSize    
derby.storage.tempDirectory    
derby.stream.error.field    
derby.stream.error.file    
derby.stream.error.method    
derby.stream.error.logSeverityLevel    
derby.system.bootAll    
derby.system.durability    
derby.system.home    
derby.user.UserName    
Internal language transformations    
Predicate transformations    
BETWEEN transformations    
LIKE transformations    
Simple IN predicate transformations    
NOT IN predicate transformations    
OR transformations    
Transitive closure    
Transitive closure on join clauses    
Transitive Closure on Search Clauses    
View transformations    
View flattening    
Predicates pushed into views or derived tables    
Subquery processing and transformations    
Materialization    
Flattening a subquery into a normal join    
Flattening a subquery into an EXISTS join    
Flattening VALUES subqueries    
DISTINCT elimination in IN, ANY, and EXISTS subqueries    
IN/ANY subquery transformation    
Outer join transformations    
Sort avoidance    
DISTINCT elimination based on a uniqueness condition    
Combining ORDER BY and DISTINCT    
Combining ORDER BY and UNION    
Aggregate processing    
COUNT(nonNullableColumn)    
Trademarks    


Tuning Derby
Apache Software FoundationTuning DerbyApache Derby
Copyright
Copyright 2004-2008 The Apache Software Foundation
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
Related information
License
The Apache License, Version 2.0
Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
About this guide
For general information about the Derby documentation, such as a complete list of books, conventions, and further reading, see Getting Started with Derby.
Purpose of this guide
This guide, Tuning Derby, explains how to set properties to configure and tune systems, databases, specific tables and indexes, and queries. This guide also provides performance tuning tips and an in-depth study of query optimization and performance issues.
Audience
This book is a reference for Derby users, typically application developers. Derby users who are not familiar with the SQL standard or the Java programming language will benefit from consulting books on those topics.
Derby users who want a how-to approach to working with Derby or an introduction to Derby concepts should read the Derby Developer's Guide. This book is for users who want to optimize and tune their application's performance.
How this guide is organized
This guide includes the following sections:
 
Working with Derby properties
An overview of how you set properties.
 
Performance tips and tricks
Quick tips on how to improve the performance of Derby applications.
 
Tuning databases and applications
A more in-depth discussion of how to improve the performance of Derby applications.
 
DML statements and performance
An in-depth study of how Derby executes queries, how the optimizer works, and how to tune query execution.
 
 
Internal language transformations
Reference on how Derby internally transforms some SQL statements for performance reasons. Not of interest to the general user.
Working with Derby properties
Properties overview
Derby lets you configure behavior or attributes of a system, a specific database, or a specific conglomerate (a table or index) through the use of properties.
Examples of behavior or attributes that you can configure are:
 
Whether to authorize users
 
Page size of tables and indexes
 
Where and whether to create an error log
 
Which databases in the system to boot
Scope of properties
You use properties to configure a Derby system, database, or conglomerate.
 
system-wide
Most properties can be set on a system-wide basis; that is, you set a property for the entire system and all its databases and conglomerates, if this is applicable. Some properties, such as error handling and automatic booting, can be configured only in this way, since they apply to the entire system. (For information about the Derby system, see the Derby Developer's Guide.)
When you change these properties, they affect any tables or indexes created after this change.
 
database-wide
Some properties can also be set on a database-wide basis. That is, the property is true for the selected database only and not for the other databases in the system unless it is set individually within each of them.
When you change these properties, they affect any tables or indexes created after this change.
 
conglomerate-specific
Beginning with Derby properties relating to conglomerates cannot be specified as part of the create-statement for the object. These properties (for example, derby.storage.pageSize) must be set at the database level prior to executing the create-statement. These storage-related properties take effect when you create a table or index, and cannot be changed during the lifetime of the conglomerate
Persistence of properties
A database-wide property always has persistence. That is, its value is stored in the database. Typically, it is in effect until you explicitly change the property or until you set a system-wide property with precedence over database-wide properties (see Precedence of properties).
A system-wide property might have persistence, depending on how you set it. If you set it programmatically, it persists only for the duration of the JVM of the application that set it. If you set it in the derby.properties file, a property persists until:
 
That value is changed
 
The file is removed from the system
 
The database is booted outside of that system
Precedence of properties
The search order for properties is:
1.
 
System-wide properties set programmatically (as a command-line option to the JVM when starting the application or within application code)
2.
 
Database-wide properties
3.
 
System-wide properties set in the derby.properties file
This means, for example, that system-wide properties set programmatically override database-wide properties and system-wide properties set in the derby.properties file, and that database-wide properties override system-wide properties set in the derby.properties file.
Protection of database-wide properties
There is one important exception to the search order for properties described above: When you set the derby.database.propertiesOnly property to true, database-wide properties cannot be overridden by system-wide properties.
This property ensures that a database's environment cannot be modified by the environment in which it is booted. Any application running in an embedded environment can set this property to true for security reasons.
Dynamic versus static properties
Most properties are dynamic; that means you can set them while Derby is running, and their values change without requiring a reboot of Derby. In some cases, this change takes place immediately; in some cases, it takes place at the next connection.
Some properties are static, which means changes to their values will not take effect while Derby is running. You must restart or set them before (or while) starting Derby.
For more information, see Dynamic or static changes to properties.
Ways of setting Derby properties
This section covers the different ways of setting properties.
System-wide properties
You can set system-wide properties programmatically (as a command-line option to the JVM when starting the application or within application code) or in the text file derby.properties.
Changing the system-wide properties programmatically
You can set properties programmatically-either in application code before booting the Derby driver or as a command-line option to the JVM when booting the application that starts up Derby. When you set properties programmatically, these properties persist only for the duration of the application. Properties set programmatically are not written to the derby.properties file or made persistent in any other way by Derby.
Note: Setting properties programmatically works only for the application that starts up Derby; for example, for an application in an embedded environment or for the application server that starts up a server product. It does not work for client applications connecting to a server that is running.
As a parameter to the JVM command line:
You can set system-wide properties as parameters to the JVM command line when starting up the application or framework in which Derby is embedded.
 
IBM Application Developer Kits
With the IBM® SDK, you set JVM system properties by using a -D flag on the Java command line. For example:
java -Dderby.system.home=C:\home\Derby\ -Dderby.storage.pageSize=8192 JDBCTest
For other JVMs, see the JVM-specific documentation on setting system properties.
Using a properties object within an application or statement:
In embedded mode, your application runs in the same JVM as Derby, so you can also set system properties within an application using a Properties object before loading the Derby JDBC driver. The following example sets derby.system.home on Windows.
Properties p = System.getProperties(); p.put("derby.system.home", "C:\databases\sample");
Note: If you pass in a Properties object as an argument to the DriverManager.getConnection call when connecting to a database, those properties are used as database connection URL attributes, not as properties of the type discussed in this book. For more information, see "java.sql.DriverManager.getConnection method" and "Setting attributes for the database connection URL" in the Derby Reference Manual.
Changing the system-wide properties by using the derby.properties file
You can set persistent system-wide properties in a text file called derby.properties, which must be placed in the directory specified by the derby.system.home property. There should be one derby.properties file per system, not per database. The file must be created in the system directory. In a client/server environment, that directory is on the server. (For more information about a Derby system and the system directory, see "Derby System" in the Derby Developer's Guide.)
Derby does not:
 
Provide this file
 
Automatically create this file for you
 
Automatically write any properties or values to this file
Instead, you must create, write, and edit this file yourself.
The file should be in the format created by the java.util.Properties.save method.
The following is the text of a sample properties file:
derby.infolog.append=true derby.storage.pageSize=8192 derby.storage.pageReservedSpace=60
Properties set this way are persistent for the system until changed, until the file is removed from the system, or until the system is booted in some other directory (in which case Derby would be looking for derby.properties in that new directory). If a database is removed from a system, system-wide properties do not "travel" with the database unless explicitly set again.
Verifying system properties
You can find out the value of a system property if you set it programmatically. You cannot find out the value of a system property if you set it in the derby.properties file.
For example, if you set the value of the derby.storage.pageSize system-wide property in your program or on the command line, the following code will retrieve its value from the System Properties object:
Properties sprops = System.getProperties(); System.out.println("derby.storage.pageSize value: " + sprops.getProperty("derby.storage.pageSize"));
You can also use Java Management Extensions (JMX) technology to obtain system information, including some settings that correspond to system properties. For details, visit the wiki page http://wiki.apache.org/db-derby/DerbyJMX and refer to the API documentation for the packages org.apache.derby.mbeans and org.apache.derby.mbeans.drda. For information on JMX technology, see http://java.sun.com/javase/technologies/core/mntr-mgmt/javamanagement/
Database-wide properties
Database-wide properties, which affect a single database, are stored within the database itself. This allows different databases within a single Derby system to have different properties and ensures that the properties are correctly set when a database is moved away from its original system or copied.
Note: You should use database-wide properties wherever possible for ease of deployment.
You set and verify database-wide properties using system procedures within SQL statements.
To set a property, you connect to the database, create a statement, and then use the SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY procedure, passing the name of the property and the value.
To check the current value of a property, you connect to the database, create a statement, and then use the SYSCS_UTIL.SYSCS_GET_DATABASE_PROPERTY function, passing in the name of the property.
If you specify an invalid value, Derby uses the default value for the property.
See the Derby Reference Manual for more information on how to use these system functions and procedures.
In a client/server environment
In a client/server environment, you must set the system properties for the server's system. That means when you are using the derby.properties file, the file exists in the server's derby.system.home directory. Client applications can set database-wide because they are set via SQL statements. Client applications can set dynamic system-wide properties in an SQL statement, as shown in the example in Using a properties object within an application or statement.
Table 1. Summary of ways to set properties
Type of property
How you set it
System-wide
 
In derby.properties
 
Programmatically (as a command-line option to the JVM when starting the application or within application code)
Database-wide
Using system procedures and functions in an SQL statement
Dynamic or static changes to properties
Note: Properties set in the derby.properties file and on the command line of the application that boots Derby are always static, because Derby reads this file and those parameters only at startup.
Only properties set in the following ways have the potential to be dynamic:
 
As database-wide properties
 
As system-wide properties via a Properties object in the application in which the Derby engine is embedded
See Derby properties, for information about specific properties.
Properties case study
Derby allows you a lot of freedom in configuring your system. This freedom can be confusing if you do not understand how properties work. You also have the option of not setting any and instead using the Derby defaults, which are tuned for a single-user embedded system.
Imagine the following scenario of an embedded environment:
Your system has a derby.properties file, a text file in the system directory, which you have created and named system_directory. Your databases have also been created in this directory. The properties file sets the following property:
 
derby.storage.pageSize = 8192
You start up your application, being sure to set the derby.system.home property appropriately:
java -Dderby.system.home=c:\system_directory MyApp
You then create a new table:
CREATE TABLE table1 (a INT, b VARCHAR(10))
Derby takes the page size of 8192 from the system-wide properties set in the derby.properties file, since the property has not been set any other way.
You shut down and then restart your application, setting the value of derby.storage.pageSize to 4096 programmatically, as a parameter to the JVM command line:
java -Dderby.system.home=c:\system_directory -Dderby.storage.pageSize=4096 MyApp CREATE TABLE anothertable (a INT, b VARCHAR(10))
The page size for the anothertable table will be 4096 bytes.
You establish a connection to the database and set the value of the page size for all new tables to 32768 as a database-wide property:
CallableStatement cs = conn.prepareCall("CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY(?, ?)"); cs.setString(1, "derby.storage.pageSize"); cs.setString(2, "32768"); cs.execute(); cs.close();
You then create a new table that automatically inherits the page size set by the property:
CREATE TABLE table2 (a INT, b VARCHAR(10))
The page size for the table2 table is 32768 bytes.
You shut down the application, then restart, this time forgetting to set the system-wide property programmatically (as a command-line option to the JVM):
java -Dderby.system.home=c:\system_directory MyApp
You then create another table:
CREATE TABLE table4 (a INT, b VARCHAR(10))
Derby uses the persistent database-wide property of 32768 for this table, since the database-wide property set in the previous session is persistent and overrides the system-wide property set in the derby.properties file.
What you have is a situation in which three different tables each get a different page size, even though the derby.properties file remained constant.
Remove the derby.properties file from the system or the database from its current location (forgetting to move the file with it), and you could get yet another value for a new table.
To avoid this situation, be consistent in the way you set properties.
Performance tips and tricks
This chapter lists tips for improving the performance of your Derby application. For a more in-depth discussion of performance, see Tuning databases and applications.
The tips
 
Use prepared statements with substitution parameters to save on costly compilation time. Prepared statements using substitution parameters significantly improves performance in applications using standard statements.
 
Create indexes, and make sure they are being used. Indexes speed up queries dramatically if the table is much larger than the number of rows retrieved.
 
 
Tune the size of database pages. Using large database pages has provided a performance improvement of up to 50%. There are also other storage parameters worth tweaking. If you use large database pages, increase the amount of memory available to Derby.
 
 
 
Tune database booting/class loading. System startup time can be improved by reducing the number of databases in the system directory.
 
Avoid inserts in autocommit mode if possible. Speed up insert performance.
 
Customize the optimizer methods for table functions. Force more efficient join orders for queries which use table functions.
These tips might solve your particular performance problem. Be sure to visit the Support section of Derby's Web site for up-to-date performance tips and tricks.
Use prepared statements with substitution parameters
In Derby, as with most relational database management systems, performing an SQL request has two steps: compiling the request and executing it. When you use prepared statements (java.sql.PreparedStatement) instead of statements (java.sql.Statement) you can help Derby avoid unnecessary compilation, which saves time. In general, any query that you will use more than once should be a prepared statement.
For more information, see Avoiding compiling SQL statements.
Using prepared statements can result in significant performance improvement, depending on the complexity of the query. More complex queries show greater benefit from being prepared.
Create indexes, and make sure they are being used
By creating indexes on columns by which you often search a table, you can reduce the number of rows that Derby has to scan, thus improving performance. Depending on the size of the table and the number of rows returned, the improvement can be dramatic. Indexes work best when the number of rows returned from the query is a fraction of the number of rows in the table.
There are some trade-offs in using indexes: indexes speed up searches but slow down inserts and updates. As a general rule, every table should have at least a primary key constraint.
See Always create indexes for more information.
Increase the size of the data page cache
You can increase the size of a database's data page cache, which consists of the data pages kept in memory. When Derby can access a database page from the cache instead of reading it from disk, it can return data much more quickly.
The default size of the data page cache is 1000 pages. In a multi-user environment, or in an environment where the user accesses a lot of data, increase the size of the cache. You configure its size with the derby.storage.pageCacheSize property. For more information about how to set this property and how to estimate memory use, see derby.storage.pageCacheSize.
Note: Derby can run even with a small amount of memory and even with a small data page cache, although it might perform poorly. Increasing the amount of memory available to Derby and increasing the size of the data page cache improve performance.
In addition, you might want to prime all the caches in the background to make queries run faster when the user gets around to running them.
These caches include:
 
The page (user data) cache (described above)
Prime this cache by selecting from much-used tables that are expected to fit into the data page cache.
 
The data dictionary cache
The cache that holds information stored in the system tables. You can prime this cache with a query that selects from commonly used user tables.
 
The statement cache
The cache that holds database-specific Statements (including PreparedStatements). You can prime this cache by preparing common queries ahead of time in a separate thread.
Tune the size of database pages
Stick with 4K as the page size (the default, and the size operating systems use) unless:
 
You are storing large objects.
 
You have very large tables (over 10,000 rows).
For very large tables, large pages reduces the number of I/Os required.
 
For read-only applications, use a large page size (for example, 32K) with a pageReservedSpace of 0.
You might need to experiment with page size to find out what works best for your application and database.
Performance trade-offs of large pages
Using large database pages benefits database performance, notably decreasing I/O time. Derby automatically tunes for the database page size. If you have long columns, the default page size for the table is set to 32768 bytes. Otherwise, the default is 4096 bytes. You can change the default database page size with the derby.storage.pageSize property. For example:
derby.storage.pageSize=8192
Note: Large database pages require more memory.
If row size is large, generally page size should be correspondingly large. If row size is small, page size should be small. Another rough guideline is to try to have at least 10 average-sized rows per page (up to 32K).
Use a larger page size for tables with large columns or rows. Maximum page size allowed is 32k.
However, some applications involve rows whose size will vary considerably from user to user. In that situation, it is hard to predict what effect page size will have on performance.
If a table contains one large column along with several small columns, put the large column at the end of the row, so that commonly used columns will not be moved to overflow pages. Do not index large columns.
Large page size for indexes improves performance considerably.
When large page size does not improve performance:
 
Selective Queries
If your application's queries are very selective and use an index, large page size does not provide much benefit and potentially degrades performance because a larger page takes longer to read.
When large page size is not desirable:
 
Limited memory
Large database pages reduce I/O time because Derby can access more data with fewer I/Os. However, large pages require more memory. Derby allocates a bulk number of database pages in its page cache by default. If the page size is large, the system might run out of memory.
Here's a rough guideline: If the system is running Windows 95 and has more than 32 MB (or Windows NT and has more than 64 MB), it is probably beneficial to use 8K rather than 4K as the default page size.
Use the -mx flag as an optional parameter to the JVM to give the JVM more memory upon startup.
For example:
java -mx64 myApp
 
Limited disk space
If you cannot afford the overhead of the minimum two pages per table, keep your page sizes small.
Avoid expensive queries
Some queries can, and should, be avoided. Two examples:
SELECT DISTINCT nonIndexedCol FROM HugeTable SELECT * FROM HugeTable ORDER BY nonIndexedColumn
Use the appropriate getXXX and setXXX methods for the type
For performance reasons, use the recommended getXXX method when retrieving values, and use the recommended setXXX method when setting values for parameters.
JDBC is permissive. It lets you use java.sql.ResultSet.getFloat to retrieve an int, java.sql.ResultSet.getObject to retrieve any type, and so on. (java.sql.ResultSet and java.sql.CallableStatement provide getXXX methods, and java .sql.PreparedStatement and java.sql.CallableStatement provide setXXX methods.) This permissiveness is convenient but expensive in terms of performance.
The following table shows the recommended getXXX methods for given java.sql (JDBC) types, and their corresponding SQL types.
Table 2. Mapping of java.sql.Types to SQL types
Recommended getXXX Method
java.sql.Types
SQL types
getLong
BIGINT
BIGINT
getBytes
BINARY
CHAR FOR BIT DATA
getBlob
BLOB
BLOB
getString
CHAR
CHAR
getClob
CLOB
CLOB
getDate
DATE
DATE
getBigDecimal
DECIMAL
DECIMAL
getDouble
DOUBLE
DOUBLE PRECISION
getDouble
FLOAT
DOUBLE PRECISION
getInt
INTEGER
INTEGER
getBinaryStream
LONGVARBINARY
LONG VARCHAR FOR BIT DATA
getAsciiStream, getUnicodeStream
LONGVARCHAR
LONG VARCHAR
getBigDecimal
NUMERIC
DECIMAL
getFloat
REAL
REAL
getShort
SMALLINT
SMALLINT
getTime
TIME
TIME
getTimestamp
TIMESTAMP
TIMESTAMP
getBytes
VARBINARY
VARCHAR FOR BIT DATA
getString
VARCHAR
VARCHAR
None supported. You must use XMLSERIALIZE and then the corresponding getXXX method.
SQLXML
XML
Tune database booting/class loading
By default, Derby does not boot databases (and some core Derby classes) in the system at Derby startup but only at connection time. For multi-user systems, you might want to reduce connection time by booting one or all databases at startup instead.
For embedded systems, you might want to boot the database in a separate thread (either as part of the startup, or in a connection request).
Avoid inserts in autocommit mode if possible
Inserts can be painfully slow in autocommit mode because each commit involves an update of the log on the disk for each INSERT statement. The commit will not return until a physical disk write is executed. To speed things up:
 
Run in autocommit false mode, execute a number of inserts in one transaction, and then explicitly issue a commit.
 
If your application allows an initial load into the table, you can use the import procedures to insert data into a table. Derby will not log the individual inserts when loading into an empty table using these interfaces. See the Derby Tools and Utilities Guide Guide for more information on the import procedures.
Customize the optimizer methods for table functions
The optimizer makes hard-coded guesses about how to calculate the cost of a user-written Derby-style table function. For this reason, the optimizer may place a table function in an inefficient position in the join order. You can give the optimizer more information so that it makes better choices. See "Programming Derby-style table functions" in the Derby Developer's Guide.
More tips
Shut down the system properly
Derby features crash recovery that restores the state of committed transactions in the event that the database exits unexpectedly, for example during a power failure. The recovery processing happens the next time the database is started after the unexpected exit. Your application can reduce the amount of work that the database has to do to start up the next time by shutting it down in an orderly fashion. See "Shutting Down Derby or an Individual Database" in the Derby Developer's Guide.
The Derby utilities all perform an "orderly" shutdown.
Put Derby first in your classpath
The structure of your classpath can affect Derby startup time and the time required to load a particular class.
The classpath is searched linearly, so locate Derby's libraries at the beginning of the classpath so that they are found first. If the classpath first points to a directory that contains multiple files, booting Derby can be very slow.
Tuning databases and applications
Performance tips and tricks, provided some quick tips for improving performance. This chapter, while covering some of the same ground, provides more background on the basic design issues for improving performance. It also explains how to work with RunTimeStatistics.
Application and database design issues
Things that you can do to improve the performance of Derby applications fall into three categories.
Avoiding table scans of large tables
Derby is fast and efficient, but when tables are huge, scanning tables might take longer than a user would expect. It's even worse if you then ask Derby to sort this data.
Things that you can do to avoid table scans fall into two categories.
Always create indexes
Have you ever thought what it would be like to look up a phone number in the phone book of a major metropolitan city if the book were not indexed by name? For example, to look up the phone number for John Jones, you could not go straight to the J page. You would have to read the entire book. That is what a table scan is like. Derby has to read the entire table to retrieve what you are looking for unless you create useful indexes on your table.
Create useful indexes:
Indexes are useful when a query contains a WHERE clause.
Without a WHERE clause, Derby is supposed to return all the data in the table, and so a table scan is the correct (if not desirable) behavior. (More about that in Prevent the user from issuing expensive queries.)
Derby creates indexes on tables in the following situations:
 
When you define a primary key, unique, or foreign key constraint on a table. See "CONSTRAINT clause" in the Derby Reference Manual for more information.
 
When you explicitly create an index on a table with a CREATE INDEX statement.
For an index to be useful for a particular statement, one of the columns in the statement's WHERE clause must be the first column in the index's key.
Note: For a complete discussion of how indexes work and when they are useful, see What is an index? and Index use and access paths.
Indexes provide some other benefits as well:
 
If all the data requested are in the index, Derby does not have to go to the table at all. (See Covering indexes.)
 
For operations that require a sort (ORDER BY), if Derby uses the index to retrieve the data, it does not have to perform a separate sorting step for some of these operations in some situations. (See About the optimizer's choice of sort avoidance.)
Note: Derby does not support indexing on columns with data types like BLOB, CLOB, and XML.
Make sure indexes are being used, and rebuild them:
If an index is useful for a query, Derby is probably using it. However, you need to make sure. Analyze the way Derby is executing your application's queries. See Analyzing statement execution for information on how to do this.
In addition, over time, index pages fragment. Rebuilding indexes improves performance significantly in these situations. To rebuild an index, drop it and then re-create it.
Think about index order:
Derby allows you to create index columns in descending order in addition to creating them in ascending order, the default. Descending indexes provide performance benefits for the following kinds of queries that require sorting data in descending order.
To ensure performance benefits, verify that the descending index is being used. See Analyzing statement execution for information on how to do this.
Think about join order:
For some queries, join order can make the difference between a table scan (expensive) and an index scan (cheap). Here's an example:
select ht.hotel_id, ha.stay_date, ht.depart_time from hotels ht, Hotelavailability ha where ht.hotel_id = ha.hotel_id and ht.room_number = ha.room_number and ht.bed_type = 'KING' and ht.smoking_room = 'NO' order by ha.stay_date
If Derby chooses Hotels as the outer table, it can use the index on Hotels to retrieve qualifying rows. Then it need only look up data in HotelAv