3. Performance Facts
โMore than half of application performance
bottlenecks originate in the databaseโ
AppDynamics - http://www.appdynamics.com/database/
5. Poor manโs JDBC
โข High response time
โข Low throughput
Photo by Amit Patel CC BY 2.0 https://www.flickr.com/photos/amitp/6069412747/
6. State of the art JDBC
โข Low response time
โข High throughput
Photo by zoetnet CC BY 2.0 https://www.flickr.com/photos/zoetnet/14288129197/
7. Response time
โข connection acquisition time
โข statements submission time
โข statements execution time
โข result set fetching time
โข idle time prior to releasing the database connection
๐ = ๐ก ๐๐๐ + ๐ก ๐๐๐ + ๐ก ๐๐ฅ๐๐ + ๐ก ๐๐๐ + ๐ก๐๐๐๐
20. Oracle Statement batching
โข For Statement and CallableStatement,
the Oracle JDBC Driver doesnโt actually support batching,
each statement being executed separately.
21. MySQL Statement batching
โข By default, the MySQL JDBC driver doesnโt send the batched
statements in a single request.
โข The rewriteBatchedStatements connection property
adds all batched statements to a String buffer.
30. SQL Server server-side statement caching
โข Execution plan cache
โข Parameter sniffing
โข Force recompile
SELECT *
FROM task
WHERE status = ?
OPTION(RECOMPILE);
31. PostgreSQL server-side statement caching
โข Prior to 9.2 โ execution plan caching
โข 9.2 โ optimization and planning are deferred
โข The prepareThreshold connection property
32. MySQL server-side statement caching
โข No execution plan cache
โข Since Connector/J 5.0.5 PreparedStatements are only
emulated
โข To activate server-side prepared statements:
โข useServerPrepStmts
โข cachePrepStmts
35. Oracle implicit client-side statement caching
โข Can be disabled on a per statement basis
if (statement.isPoolable()) {
statement.setPoolable(false);
}
36. Oracle explicit client-side statement caching
โข Caches both metadata and execution state with data
OracleConnection oracleConnection =
(OracleConnection) connection;
oracleConnection.setExplicitCachingEnabled(true);
oracleConnection.setStatementCacheSize(cacheSize);
39. PostgreSQL Server client-side statement caching
โข PostgreSQL JDBC Driver 9.4-1202 makes client-side
statement connection-bound instead of statement-bound
โข Configurable:
โข preparedStatementCacheQueries (default is 256)
โข preparedStatementCacheSizeMiB (default is 5MB)
โข Statement.setPoolable(false) is not supported
40. MySQL Server client-side statement caching
โข Configurable:
โข cachePrepStmts (default is false)
Required for server-side statement caching as well
โข prepStmtCacheSize (default is 25)
โข prepStmtCacheSqlLimit (default is 256)
โข Statement.setPoolable(false) works for client-side
statements only
42. Oracle ResultSet fetch size
โข Default fetch size is 10
โข Oracle 10i and 11g JDBC Driver maximum ResultSet size
memory preallocation
โข VARCHAR2(4000) โ allocates 8000 bytes (even for 1 character)
โข Memory buffers are recycled only when using Statement caching
โข Oracle 12c allocates memory on demand
โข VARCHAR2(4000) โ 15 bytes + the actual row column size
43. SQL Server ResultSet fetch size
โข Adaptive buffering
โข Only for the default read-only and forward-only ResultSet
โข Updatable cursors use fixed data blocks
44. PostgreSQL ResultSet fetch size
โข Fetch all โ one database roundtrip
โข Custom fetch size โ database cursor
45. MySQL ResultSet fetch size
โข Fetch all โ one database roundtrip
โข Streaming โ only one record at a time
47. ResultSet size
โข Avoid fetching data that is not required
โข Hibernate addresses the max-size vendor-specific SQL
statement syntax
48. SQL:2008 ResultSet size limit
โข Oracle 12c, SQL Server 2012 and PostgreSQL 8.4
SELECT
pc.id AS pc_id, p.title AS p_title
FROM post_comment pc
INNER JOIN post p ON p.id = pc.post_id
ORDER BY pc_id
OFFSET ? ROWS
FETCH FIRST (?) ROWS ONLY;
49. Oracle ResultSet size limit
SELECT *
FROM (
SELECT
pc.id AS pc_id, p.title AS p_title
FROM post_comment pc
INNER JOIN post p ON p.id = pc.post_id
ORDER BY pc_id
)
WHERE ROWNUM <= ?
50. SQL Server ResultSet size limit
SELECT
TOP (?) pc.id AS pc_id, p.title AS p_title
FROM post_comment pc
INNER JOIN post p ON p.id = pc.post_id
ORDER BY pc_id
51. PostgreSQL and MySQL ResultSet size limit
SELECT
pc.id AS pc_id, p.title AS p_title
FROM post_comment pc
INNER JOIN post p ON p.id = pc.post_id
ORDER BY pc_id
LIMIT ?
52. Statement max rows
โข Vendor-independent syntax
โข Might not influence the execution plan
โข According to the documentation:
โIf the limit is exceeded, the excess rows are silently dropped.โ
statement.setMaxRows(maxRows);
53. Max size: 1 million vs 100 rows
Fetch all Fetch max rows Fetch limit
0
500
1000
1500
2000
2500
3000
3500
4000
4500
5000
Time(ms)
DB_A DB_B DB_C DB_D
54. Fetching too many columns
โข Fetching all column (ORM tools)
SELECT *
FROM post_comment pc
INNER JOIN post p ON p.id = pc.post_id
INNER JOIN post_details pd ON p.id = pd.id
55. Fetching too many columns
โข Fetching a custom SQL projection
SELECT pc.version
FROM post_comment pc
INNER JOIN post p ON p.id = pc.post_id
INNER JOIN post_details pd ON p.id = pd.id
56. Fetching too many columns performance impact
All columns Custom projection
0
5
10
15
20
25
30
Time(ms)
DB_A DB_B DB_C DB_D
57. Processing Logic
โข Hibernate defers connection acquisition
โข Release connection as soon as possible
๐ = ๐ก ๐๐๐ + ๐ก ๐๐๐ + ๐ก ๐๐ฅ๐๐ + ๐ก ๐๐๐ + ๐ก๐๐๐๐