Repository: ignite Updated Branches: refs/heads/ignite-sql-cache-stmt [created] 53f0c1d23
Added cache for PreparedStatements. Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/53f0c1d2 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/53f0c1d2 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/53f0c1d2 Branch: refs/heads/ignite-sql-cache-stmt Commit: 53f0c1d23e12fbdd915aabf3289970da54ac5275 Parents: 07f5a62 Author: sboikov <[email protected]> Authored: Mon Nov 23 11:43:43 2015 +0300 Committer: sboikov <[email protected]> Committed: Mon Nov 23 11:43:43 2015 +0300 ---------------------------------------------------------------------- .../query/h2/GridH2ResultSetIterator.java | 19 ++++-- .../processors/query/h2/IgniteH2Indexing.java | 66 +++++++++++++++----- .../query/h2/twostep/GridMapQueryExecutor.java | 17 ++--- .../h2/twostep/GridReduceQueryExecutor.java | 12 ++-- 4 files changed, 78 insertions(+), 36 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/53f0c1d2/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/GridH2ResultSetIterator.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/GridH2ResultSetIterator.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/GridH2ResultSetIterator.java index 2c67638..3603bb5 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/GridH2ResultSetIterator.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/GridH2ResultSetIterator.java @@ -41,14 +41,19 @@ public abstract class GridH2ResultSetIterator<T> extends GridCloseableIteratorAd protected final Object[] row; /** */ + private final boolean closeStmt; + + /** */ private boolean hasRow; /** * @param data Data array. + * @param closeStmt If {@code true} closes result set statement when iterator is closed. * @throws IgniteCheckedException If failed. */ - protected GridH2ResultSetIterator(ResultSet data) throws IgniteCheckedException { + protected GridH2ResultSetIterator(ResultSet data, boolean closeStmt) throws IgniteCheckedException { this.data = data; + this.closeStmt = closeStmt; if (data != null) { try { @@ -115,11 +120,13 @@ public abstract class GridH2ResultSetIterator<T> extends GridCloseableIteratorAd // Nothing to close. return; - try { - U.closeQuiet(data.getStatement()); - } - catch (SQLException e) { - throw new IgniteCheckedException(e); + if (closeStmt) { + try { + U.closeQuiet(data.getStatement()); + } + catch (SQLException e) { + throw new IgniteCheckedException(e); + } } U.closeQuiet(data); http://git-wip-us.apache.org/repos/asf/ignite/blob/53f0c1d2/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java index d5efebf..6cf65b6 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java @@ -124,6 +124,7 @@ import org.h2.table.Column; import org.h2.table.IndexColumn; import org.h2.table.Table; import org.h2.tools.Server; +import org.h2.util.SmallLRUCache; import org.h2.util.Utils; import org.h2.value.DataType; import org.h2.value.Value; @@ -266,6 +267,14 @@ public class IgniteH2Indexing implements GridQueryIndexing { /** */ private volatile GridKernalContext ctx; + /** */ + private final ThreadLocal<SmallLRUCache<String, PreparedStatement>> stmtCache = + new ThreadLocal<SmallLRUCache<String, PreparedStatement>>() { + @Override protected SmallLRUCache<String, PreparedStatement> initialValue() { + return SmallLRUCache.newInstance(256); + } + }; + /** * @param space Space. * @return Connection. @@ -280,6 +289,32 @@ public class IgniteH2Indexing implements GridQueryIndexing { } /** + * @param c Connection. + * @param sql SQL. + * @param useStmtCache If {@code true} uses statement cache. + * @return Prepared statement. + * @throws SQLException If failed. + */ + private PreparedStatement prepareStatement(Connection c, String sql, boolean useStmtCache) throws SQLException { + if (useStmtCache) { + SmallLRUCache<String, PreparedStatement> cache = stmtCache.get(); + + PreparedStatement stmt = cache.get(sql); + + if (stmt != null) + return stmt; + + stmt = c.prepareStatement(sql); + + cache.put(sql, stmt); + + return stmt; + } + else + return c.prepareStatement(sql); + } + + /** * Gets DB connection. * * @param schema Whether to set schema for connection or not. @@ -648,7 +683,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { try { Connection conn = connectionForThread(schema(spaceName)); - ResultSet rs = executeSqlQueryWithTimer(spaceName, conn, qry, params); + ResultSet rs = executeSqlQueryWithTimer(spaceName, conn, qry, params, true); List<GridQueryFieldMetadata> meta = null; @@ -710,15 +745,16 @@ public class IgniteH2Indexing implements GridQueryIndexing { * @param conn Connection,. * @param sql Sql query. * @param params Parameters. + * @param useStmtCache If {@code true} uses statement cache. * @return Result. * @throws IgniteCheckedException If failed. */ - private ResultSet executeSqlQuery(Connection conn, String sql, Collection<Object> params) + private ResultSet executeSqlQuery(Connection conn, String sql, Collection<Object> params, boolean useStmtCache) throws IgniteCheckedException { PreparedStatement stmt; try { - stmt = conn.prepareStatement(sql); + stmt = prepareStatement(conn, sql, useStmtCache); } catch (SQLException e) { throw new IgniteCheckedException("Failed to parse SQL query: " + sql, e); @@ -747,18 +783,23 @@ public class IgniteH2Indexing implements GridQueryIndexing { /** * Executes sql query and prints warning if query is too slow.. * + * @param space Space name. * @param conn Connection,. * @param sql Sql query. * @param params Parameters. + * @param useStmtCache If {@code true} uses statement cache. * @return Result. * @throws IgniteCheckedException If failed. */ - public ResultSet executeSqlQueryWithTimer(String space, Connection conn, String sql, - @Nullable Collection<Object> params) throws IgniteCheckedException { + public ResultSet executeSqlQueryWithTimer(String space, + Connection conn, + String sql, + @Nullable Collection<Object> params, + boolean useStmtCache) throws IgniteCheckedException { long start = U.currentTimeMillis(); try { - ResultSet rs = executeSqlQuery(conn, sql, params); + ResultSet rs = executeSqlQuery(conn, sql, params, useStmtCache); long time = U.currentTimeMillis() - start; @@ -767,7 +808,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { if (time > longQryExecTimeout) { String msg = "Query execution is too long (" + time + " ms): " + sql; - ResultSet plan = executeSqlQuery(conn, "EXPLAIN " + sql, params); + ResultSet plan = executeSqlQuery(conn, "EXPLAIN " + sql, params, false); plan.next(); @@ -803,7 +844,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { String sql = generateQuery(qry, tbl); - return executeSqlQueryWithTimer(space, conn, sql, params); + return executeSqlQueryWithTimer(space, conn, sql, params, true); } /** @@ -932,7 +973,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { PreparedStatement stmt; try { - stmt = c.prepareStatement(sqlQry); + stmt = prepareStatement(c, sqlQry, true); } catch (SQLException e) { throw new CacheException("Failed to parse query: " + sqlQry, e); @@ -957,9 +998,6 @@ public class IgniteH2Indexing implements GridQueryIndexing { catch (SQLException e) { throw new CacheException(e); } - finally { - U.close(stmt, log); - } if (log.isDebugEnabled()) log.debug("Parsed query: `" + sqlQry + "` into two step query: " + twoStepQry); @@ -1889,7 +1927,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { * @throws IgniteCheckedException If failed. */ protected FieldsIterator(ResultSet data) throws IgniteCheckedException { - super(data); + super(data, false); } /** {@inheritDoc} */ @@ -1914,7 +1952,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { * @throws IgniteCheckedException If failed. */ protected KeyValIterator(ResultSet data) throws IgniteCheckedException { - super(data); + super(data, false); } /** {@inheritDoc} */ http://git-wip-us.apache.org/repos/asf/ignite/blob/53f0c1d2/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java index b4e1932..21541ec 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java @@ -451,8 +451,11 @@ public class GridMapQueryExecutor { int i = 0; for (GridCacheSqlQuery qry : qrys) { - ResultSet rs = h2.executeSqlQueryWithTimer(req.space(), h2.connectionForSpace(req.space()), qry.query(), - F.asList(qry.parameters())); + ResultSet rs = h2.executeSqlQueryWithTimer(req.space(), + h2.connectionForSpace(req.space()), + qry.query(), + F.asList(qry.parameters()), + true); if (ctx.event().isRecordable(EVT_CACHE_QUERY_EXECUTED)) { ctx.event().record(new CacheQueryExecutedEvent<>( @@ -820,17 +823,7 @@ public class GridMapQueryExecutor { closed = true; - Statement stmt; - - try { - stmt = rs.getStatement(); - } - catch (SQLException e) { - throw new IllegalStateException(e); // Must not happen. - } - U.close(rs, log); - U.close(stmt, log); } } http://git-wip-us.apache.org/repos/asf/ignite/blob/53f0c1d2/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java index f515a78..c8e0d78 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridReduceQueryExecutor.java @@ -594,7 +594,7 @@ public class GridReduceQueryExecutor { GridCacheSqlQuery rdc = qry.reduceQuery(); - res = h2.executeSqlQueryWithTimer(space, r.conn, rdc.query(), F.asList(rdc.parameters())); + res = h2.executeSqlQueryWithTimer(space, r.conn, rdc.query(), F.asList(rdc.parameters()), true); } for (GridMergeTable tbl : r.tbls) { @@ -941,7 +941,7 @@ public class GridReduceQueryExecutor { List<List<?>> lists = new ArrayList<>(); for (int i = 0, mapQrys = qry.mapQueries().size(); i < mapQrys; i++) { - ResultSet rs = h2.executeSqlQueryWithTimer(space, c, "SELECT PLAN FROM " + table(i), null); + ResultSet rs = h2.executeSqlQueryWithTimer(space, c, "SELECT PLAN FROM " + table(i), null, false); lists.add(F.asList(getPlan(rs))); } @@ -956,7 +956,11 @@ public class GridReduceQueryExecutor { GridCacheSqlQuery rdc = qry.reduceQuery(); - ResultSet rs = h2.executeSqlQueryWithTimer(space, c, "EXPLAIN " + rdc.query(), F.asList(rdc.parameters())); + ResultSet rs = h2.executeSqlQueryWithTimer(space, + c, + "EXPLAIN " + rdc.query(), + F.asList(rdc.parameters()), + false); lists.add(F.asList(getPlan(rs))); @@ -1179,7 +1183,7 @@ public class GridReduceQueryExecutor { * @throws IgniteCheckedException If failed. */ protected Iter(ResultSet data) throws IgniteCheckedException { - super(data); + super(data, false); } /** {@inheritDoc} */
