You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2015/11/23 09:43:57 UTC

ignite git commit: Added cache for PreparedStatements.

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 <sb...@gridgain.com>
Authored: Mon Nov 23 11:43:43 2015 +0300
Committer: sboikov <sb...@gridgain.com>
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} */