You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ja...@apache.org on 2014/10/09 02:02:06 UTC

[1/2] git commit: PHOENIX-1328 Update ANALYZE syntax to collect stats on index tables and all tables (ramkrishna.s.vasudevan)

Repository: phoenix
Updated Branches:
  refs/heads/3.0 be6d6f7a8 -> 836140b93


PHOENIX-1328 Update ANALYZE syntax to collect stats on index tables and all tables (ramkrishna.s.vasudevan)

Conflicts:
	phoenix-core/src/main/antlr3/PhoenixSQL.g
	phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
	phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
	phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStats.java
	phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStatsImpl.java


Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/951cae0f
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/951cae0f
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/951cae0f

Branch: refs/heads/3.0
Commit: 951cae0f5487fae8561f6ab2448154efe8def9da
Parents: be6d6f7
Author: James Taylor <jt...@salesforce.com>
Authored: Wed Oct 8 12:21:06 2014 -0700
Committer: James Taylor <jt...@salesforce.com>
Committed: Wed Oct 8 14:27:57 2014 -0700

----------------------------------------------------------------------
 .../org/apache/phoenix/end2end/ArrayIT.java     |  2 +-
 .../phoenix/end2end/ParallelIteratorsIT.java    | 40 ++++++++++++++--
 .../org/apache/phoenix/end2end/QueryIT.java     |  2 +-
 .../phoenix/end2end/StatsCollectorIT.java       | 10 ++--
 .../salted/SaltedTableUpsertSelectIT.java       |  2 +-
 phoenix-core/src/main/antlr3/PhoenixSQL.g       | 11 +++--
 .../apache/phoenix/jdbc/PhoenixStatement.java   | 14 +++---
 .../apache/phoenix/parse/ParseNodeFactory.java  |  5 +-
 .../parse/UpdateStatisticsStatement.java        | 25 +++++++++-
 .../apache/phoenix/schema/MetaDataClient.java   | 26 +++++++++--
 .../java/org/apache/phoenix/schema/PTable.java  |  3 ++
 .../org/apache/phoenix/schema/PTableImpl.java   | 49 +++++++++-----------
 .../apache/phoenix/schema/stat/PTableStats.java | 34 ++++++++++----
 .../phoenix/schema/stat/PTableStatsImpl.java    | 24 +++++++---
 .../schema/stat/StatisticsCollectionScope.java  | 28 +++++++++++
 .../phoenix/schema/stat/StatisticsUtil.java     |  2 +-
 .../java/org/apache/phoenix/util/TestUtil.java  | 16 +++++--
 17 files changed, 220 insertions(+), 73 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/951cae0f/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayIT.java
index 21cfcdd..d2dbda6 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ArrayIT.java
@@ -92,7 +92,7 @@ public class ArrayIT extends BaseClientManagedTimeIT {
 	}
 
     private void analyzeTable(Connection conn, String tableWithArray) throws SQLException {
-        String analyse = "ANALYZE  "+tableWithArray;
+        String analyse = "UPDATE STATISTICS  "+tableWithArray;
 		PreparedStatement statement = conn.prepareStatement(analyse);
         statement.execute();
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/951cae0f/phoenix-core/src/it/java/org/apache/phoenix/end2end/ParallelIteratorsIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ParallelIteratorsIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ParallelIteratorsIT.java
index dd5b661..a1c6217 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/ParallelIteratorsIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/ParallelIteratorsIT.java
@@ -20,6 +20,8 @@ package org.apache.phoenix.end2end;
 import static org.apache.phoenix.util.TestUtil.STABLE_NAME;
 import static org.apache.phoenix.util.TestUtil.TEST_PROPERTIES;
 import static org.apache.phoenix.util.TestUtil.analyzeTable;
+import static org.apache.phoenix.util.TestUtil.analyzeTableColumns;
+import static org.apache.phoenix.util.TestUtil.analyzeTableIndex;
 import static org.apache.phoenix.util.TestUtil.getAllSplits;
 import static org.apache.phoenix.util.TestUtil.getSplits;
 import static org.junit.Assert.assertEquals;
@@ -43,6 +45,7 @@ import com.google.common.collect.Maps;
 @Category(NeedsOwnMiniClusterTest.class)
 public class ParallelIteratorsIT extends BaseOwnClusterHBaseManagedTimeIT {
 
+    private static final String STABLE_INDEX = "STABLE_INDEX";
     protected static final byte[] KMIN  = new byte[] {'!'};
     protected static final byte[] KMIN2  = new byte[] {'.'};
     protected static final byte[] K1  = new byte[] {'a'};
@@ -72,7 +75,7 @@ public class ParallelIteratorsIT extends BaseOwnClusterHBaseManagedTimeIT {
         Connection conn = DriverManager.getConnection(getUrl(), TEST_PROPERTIES);
         initTableValues(conn);
         
-        PreparedStatement stmt = conn.prepareStatement("ANALYZE STABLE");
+        PreparedStatement stmt = conn.prepareStatement("UPDATE STATISTICS STABLE");
         stmt.execute();
         
         List<KeyRange> keyRanges;
@@ -108,19 +111,48 @@ public class ParallelIteratorsIT extends BaseOwnClusterHBaseManagedTimeIT {
         Connection conn = DriverManager.getConnection(getUrl(), TEST_PROPERTIES);
         byte[][] splits = new byte[][] { K3, K9, KR };
         ensureTableCreated(getUrl(), STABLE_NAME, splits);
-
+        // create index
+        conn.createStatement().execute("CREATE INDEX " + STABLE_INDEX + " ON " + STABLE_NAME + "( \"value\")");
+        // before upserting
         List<KeyRange> keyRanges = getAllSplits(conn);
         assertEquals(4, keyRanges.size());
         upsert(conn, new byte[][] { KMIN, K4, K11 });
-        analyzeTable(conn);
+        // Analyze table alone
+        analyzeTableColumns(conn);
+        keyRanges = getAllSplits(conn);
+        assertEquals(7, keyRanges.size());
+        // Get all splits on the index table before calling analyze on the index table
+        List<KeyRange> indexSplits = getAllSplits(conn, STABLE_INDEX);
+        assertEquals(1, indexSplits.size());
+        // Analyze the index table alone
+        analyzeTableIndex(conn, STABLE_NAME);
+        // check the splits of the main table 
         keyRanges = getAllSplits(conn);
         assertEquals(7, keyRanges.size());
+        // check the splits on the index table
+        indexSplits = getAllSplits(conn, STABLE_INDEX);
+        assertEquals(4, indexSplits.size());
         upsert(conn, new byte[][] { KMIN2, K5, K12 });
+        // Update the stats for both the table and the index table
         analyzeTable(conn);
         keyRanges = getAllSplits(conn);
         assertEquals(10, keyRanges.size());
+        // the above analyze should have udpated the index splits also
+        indexSplits = getAllSplits(conn, STABLE_INDEX);
+        assertEquals(7, indexSplits.size());
         upsert(conn, new byte[][] { K1, K6, KP });
-        analyzeTable(conn);
+        // Update only the table
+        analyzeTableColumns(conn);
+        keyRanges = getAllSplits(conn);
+        assertEquals(13, keyRanges.size());
+        // No change to the index splits
+        indexSplits = getAllSplits(conn, STABLE_INDEX);
+        assertEquals(7, indexSplits.size());
+        analyzeTableIndex(conn, STABLE_NAME);
+        indexSplits = getAllSplits(conn, STABLE_INDEX);
+        // the above analyze should have udpated the index splits only
+        assertEquals(10, indexSplits.size());
+        // No change in main table splits
         keyRanges = getAllSplits(conn);
         assertEquals(13, keyRanges.size());
         conn.close();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/951cae0f/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryIT.java
index e6c2fc4..bcc2973 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/QueryIT.java
@@ -855,7 +855,7 @@ public class QueryIT extends BaseQueryIT {
     }
 
     private void analyzeTable(Connection conn, String tableName) throws IOException, SQLException {
-        String query = "ANALYZE " + tableName;
+        String query = "UPDATE STATISTICS " + tableName;
         conn.createStatement().execute(query);
     }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/951cae0f/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorIT.java
index fb12cce..b48e260 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/StatsCollectorIT.java
@@ -48,7 +48,7 @@ public class StatsCollectorIT extends BaseOwnClusterHBaseManagedTimeIT {
         Array array;
         conn = upsertValues(props, "t");
         // CAll the update statistics query here. If already major compaction has run this will not get executed.
-        stmt = conn.prepareStatement("ANALYZE T");
+        stmt = conn.prepareStatement("UPDATE STATISTICS T");
         stmt.execute();
         stmt = upsertStmt(conn, "t");
         stmt.setString(1, "z");
@@ -62,7 +62,7 @@ public class StatsCollectorIT extends BaseOwnClusterHBaseManagedTimeIT {
         conn.close();
         conn = DriverManager.getConnection(getUrl(), props);
         // This analyze would not work
-        stmt = conn.prepareStatement("ANALYZE T");
+        stmt = conn.prepareStatement("UPDATE STATISTICS T");
         stmt.execute();
         rs = conn.createStatement().executeQuery("SELECT k FROM T");
         assertTrue(rs.next());
@@ -88,9 +88,9 @@ public class StatsCollectorIT extends BaseOwnClusterHBaseManagedTimeIT {
         conn = upsertValues(props, "x");
         conn = upsertValues(props, "z");
         // CAll the update statistics query here
-        stmt = conn.prepareStatement("ANALYZE X");
+        stmt = conn.prepareStatement("UPDATE STATISTICS X");
         stmt.execute();
-        stmt = conn.prepareStatement("ANALYZE Z");
+        stmt = conn.prepareStatement("UPDATE STATISTICS Z");
         stmt.execute();
         stmt = upsertStmt(conn, "x");
         stmt.setString(1, "z");
@@ -113,7 +113,7 @@ public class StatsCollectorIT extends BaseOwnClusterHBaseManagedTimeIT {
         conn.close();
         conn = DriverManager.getConnection(getUrl(), props);
         // This analyze would not work
-        stmt = conn.prepareStatement("ANALYZE Z");
+        stmt = conn.prepareStatement("UPDATE STATISTICS Z");
         stmt.execute();
         rs = conn.createStatement().executeQuery("SELECT k FROM Z");
         assertTrue(rs.next());

http://git-wip-us.apache.org/repos/asf/phoenix/blob/951cae0f/phoenix-core/src/it/java/org/apache/phoenix/end2end/salted/SaltedTableUpsertSelectIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/salted/SaltedTableUpsertSelectIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/salted/SaltedTableUpsertSelectIT.java
index 690b15c..8015cbc 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/salted/SaltedTableUpsertSelectIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/salted/SaltedTableUpsertSelectIT.java
@@ -115,7 +115,7 @@ public class SaltedTableUpsertSelectIT extends BaseHBaseManagedTimeIT {
     }
     
     private void analyzeTable(Connection conn, String tableName) throws IOException, SQLException {
-        String query = "ANALYZE " + tableName;
+        String query = "UPDATE STATISTICS " + tableName;
         conn.createStatement().execute(query);
     }
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/951cae0f/phoenix-core/src/main/antlr3/PhoenixSQL.g
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/antlr3/PhoenixSQL.g b/phoenix-core/src/main/antlr3/PhoenixSQL.g
index 67fd1cc..73bee73 100644
--- a/phoenix-core/src/main/antlr3/PhoenixSQL.g
+++ b/phoenix-core/src/main/antlr3/PhoenixSQL.g
@@ -104,7 +104,9 @@ tokens
     MAXVALUE='maxvalue';
     CYCLE='cycle';
     CASCADE='cascade';
-    ANALYZE='analyze';
+    UPDATE='update';
+    STATISTICS='statistics';    
+    COLUMNS='columns';
 }
 
 
@@ -148,6 +150,9 @@ import org.apache.phoenix.schema.IllegalDataException;
 import org.apache.phoenix.schema.PDataType;
 import org.apache.phoenix.schema.PIndexState;
 import org.apache.phoenix.schema.PTableType;
+
+import org.apache.phoenix.schema.stat.StatisticsCollectionScope;
+
 import org.apache.phoenix.util.SchemaUtil;
 import org.apache.phoenix.parse.LikeParseNode.LikeType;
 }
@@ -495,8 +500,8 @@ alter_table_node returns [AlterTableStatement ret]
     ;
 
 update_statistics_node returns [UpdateStatisticsStatement ret]
-	:   ANALYZE t=from_table_name
-		{ret = factory.updateStatistics(factory.namedTable(null, t));}
+	:   UPDATE STATISTICS t=from_table_name (s=INDEX | s=ALL | s=COLUMNS)?
+		{ret = factory.updateStatistics(factory.namedTable(null, t), s == null ? StatisticsCollectionScope.getDefault() : StatisticsCollectionScope.valueOf(SchemaUtil.normalizeIdentifier(s.getText())));}
 	;
 
 prop_name returns [String ret]

http://git-wip-us.apache.org/repos/asf/phoenix/blob/951cae0f/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
index 3bd53c5..437027c 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixStatement.java
@@ -45,7 +45,6 @@ import org.apache.phoenix.compile.DropSequenceCompiler;
 import org.apache.phoenix.compile.ExplainPlan;
 import org.apache.phoenix.compile.ExpressionProjector;
 import org.apache.phoenix.compile.FromCompiler;
-import org.apache.phoenix.compile.SubqueryRewriter;
 import org.apache.phoenix.compile.GroupByCompiler.GroupBy;
 import org.apache.phoenix.compile.MutationPlan;
 import org.apache.phoenix.compile.OrderByCompiler.OrderBy;
@@ -55,6 +54,7 @@ import org.apache.phoenix.compile.RowProjector;
 import org.apache.phoenix.compile.StatementContext;
 import org.apache.phoenix.compile.StatementNormalizer;
 import org.apache.phoenix.compile.StatementPlan;
+import org.apache.phoenix.compile.SubqueryRewriter;
 import org.apache.phoenix.compile.SubselectRewriter;
 import org.apache.phoenix.compile.UpsertCompiler;
 import org.apache.phoenix.coprocessor.MetaDataProtocol;
@@ -110,6 +110,7 @@ import org.apache.phoenix.schema.RowKeyValueAccessor;
 import org.apache.phoenix.schema.Sequence;
 import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.schema.TableRef;
+import org.apache.phoenix.schema.stat.StatisticsCollectionScope;
 import org.apache.phoenix.schema.tuple.SingleKeyValueTuple;
 import org.apache.phoenix.schema.tuple.Tuple;
 import org.apache.phoenix.util.ByteUtil;
@@ -665,9 +666,8 @@ public class PhoenixStatement implements Statement, SQLCloseable, org.apache.pho
     
     private static class ExecutableUpdateStatisticsStatement extends UpdateStatisticsStatement implements
             CompilableStatement {
-
-        public ExecutableUpdateStatisticsStatement(NamedTableNode table) {
-            super(table);
+        public ExecutableUpdateStatisticsStatement(NamedTableNode table, StatisticsCollectionScope scope) {
+            super(table, scope);
         }
 
         @SuppressWarnings("unchecked")
@@ -688,7 +688,7 @@ public class PhoenixStatement implements Statement, SQLCloseable, org.apache.pho
 
                 @Override
                 public ExplainPlan getExplainPlan() throws SQLException {
-                    return new ExplainPlan(Collections.singletonList("ANALYZE"));
+                    return new ExplainPlan(Collections.singletonList("UPDATE STATISTICS"));
                 }
 
                 @Override
@@ -862,8 +862,8 @@ public class PhoenixStatement implements Statement, SQLCloseable, org.apache.pho
         }
 
         @Override
-        public UpdateStatisticsStatement updateStatistics(NamedTableNode table) {
-            return new ExecutableUpdateStatisticsStatement(table);
+        public UpdateStatisticsStatement updateStatistics(NamedTableNode table, StatisticsCollectionScope scope) {
+            return new ExecutableUpdateStatisticsStatement(table, scope);
         }
     }
     

http://git-wip-us.apache.org/repos/asf/phoenix/blob/951cae0f/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
index f5d98d4..1f6d0a4 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
@@ -46,6 +46,7 @@ import org.apache.phoenix.schema.PIndexState;
 import org.apache.phoenix.schema.PTableType;
 import org.apache.phoenix.schema.SortOrder;
 import org.apache.phoenix.schema.TypeMismatchException;
+import org.apache.phoenix.schema.stat.StatisticsCollectionScope;
 import org.apache.phoenix.util.SchemaUtil;
 
 import com.google.common.collect.ListMultimap;
@@ -347,8 +348,8 @@ public class ParseNodeFactory {
         return new DivideParseNode(children);
     }
 
-    public UpdateStatisticsStatement updateStatistics(NamedTableNode table) {
-      return new UpdateStatisticsStatement(table);
+    public UpdateStatisticsStatement updateStatistics(NamedTableNode table, StatisticsCollectionScope scope) {
+      return new UpdateStatisticsStatement(table, scope);
     }
 
 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/951cae0f/phoenix-core/src/main/java/org/apache/phoenix/parse/UpdateStatisticsStatement.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/UpdateStatisticsStatement.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/UpdateStatisticsStatement.java
index 9eff74a..db8b7b5 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/UpdateStatisticsStatement.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/UpdateStatisticsStatement.java
@@ -17,10 +17,31 @@
  */
 package org.apache.phoenix.parse;
 
-public class UpdateStatisticsStatement extends SingleTableStatement {
+import static org.apache.phoenix.schema.stat.StatisticsCollectionScope.ALL;
+import static org.apache.phoenix.schema.stat.StatisticsCollectionScope.COLUMNS;
+import static org.apache.phoenix.schema.stat.StatisticsCollectionScope.INDEX;
+
+import org.apache.phoenix.schema.stat.StatisticsCollectionScope;
+
+import com.sun.istack.NotNull;
 
-    public UpdateStatisticsStatement(NamedTableNode table) {
+
+public class UpdateStatisticsStatement extends SingleTableStatement {
+    private final StatisticsCollectionScope scope;
+    public UpdateStatisticsStatement(NamedTableNode table, @NotNull StatisticsCollectionScope scope) {
         super(table, 0);
+        this.scope = scope;
+    }
+
+    public boolean updateColumns() {
+        return scope == COLUMNS || scope == ALL;
+    }
+
+    public boolean updateIndex() {
+        return scope == INDEX || scope == ALL;
     }
 
+    public boolean updateAll() {
+        return scope == ALL;
+    };
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/951cae0f/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
index c0947b6..8bb91b4 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/MetaDataClient.java
@@ -471,12 +471,31 @@ public class MetaDataClient {
         return connection.getQueryServices().updateData(plan);
     }
 
-    public MutationState updateStatistics(UpdateStatisticsStatement updateStatisticsStmt) throws SQLException {
+    public MutationState updateStatistics(UpdateStatisticsStatement updateStatisticsStmt)
+            throws SQLException {
         // Check before updating the stats if we have reached the configured time to reupdate the stats once again
-        long msMinBetweenUpdates = connection.getQueryServices().getProps()
-                .getLong(QueryServices.MIN_STATS_UPDATE_FREQ_MS_ATTRIB, QueryServicesOptions.DEFAULT_MIN_STATS_UPDATE_FREQ_MS);
+        final long msMinBetweenUpdates = connection
+                .getQueryServices()
+                .getProps()
+                .getLong(QueryServices.MIN_STATS_UPDATE_FREQ_MS_ATTRIB,
+                        QueryServicesOptions.DEFAULT_MIN_STATS_UPDATE_FREQ_MS);
         ColumnResolver resolver = FromCompiler.getResolver(updateStatisticsStmt, connection);
         PTable table = resolver.getTables().get(0).getTable();
+        List<PTable> indexes = table.getIndexes();
+        List<PTable> tables = Lists.newArrayListWithExpectedSize(1 + indexes.size());
+        if (updateStatisticsStmt.updateColumns()) {
+            tables.add(table);
+        }
+        if (updateStatisticsStmt.updateIndex()) {
+            tables.addAll(indexes);
+        }
+        for(PTable pTable : tables) {
+            updateStatisticsInternal(msMinBetweenUpdates, pTable);
+        }
+        return new MutationState(1, connection);
+    }
+
+    private MutationState updateStatisticsInternal(long msMinBetweenUpdates, PTable table) throws SQLException {
         PName physicalName = table.getPhysicalName();
         byte[] tenantIdBytes = ByteUtil.EMPTY_BYTE_ARRAY;
         Long scn = connection.getSCN();
@@ -1176,6 +1195,7 @@ public class MetaDataClient {
             
             // Bootstrapping for our SYSTEM.TABLE that creates itself before it exists 
             if (SchemaUtil.isMetaTable(schemaName,tableName)) {
+                // TODO: what about stats for system catalog?
                 PTable table = PTableImpl.makePTable(tenantId,PNameFactory.newName(schemaName), PNameFactory.newName(tableName), tableType,
                         null, MetaDataProtocol.MIN_TABLE_TIMESTAMP, PTable.INITIAL_SEQ_NUM,
                         PNameFactory.newName(QueryConstants.SYSTEM_TABLE_PK_NAME), null, columns, null, Collections.<PTable>emptyList(), 

http://git-wip-us.apache.org/repos/asf/phoenix/blob/951cae0f/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
index 5bd2cf2..f818b92 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTable.java
@@ -24,6 +24,7 @@ import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.io.Writable;
 import org.apache.phoenix.hbase.index.util.KeyValueBuilder;
 import org.apache.phoenix.index.IndexMaintainer;
+import org.apache.phoenix.schema.stat.PTableStats;
 
 
 /**
@@ -280,4 +281,6 @@ public interface PTable extends Writable {
     PTableKey getKey();
     
     int getEstimatedSize();
+
+    PTableStats getTableStats();
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/951cae0f/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
index 6feeaa1..c909345 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
@@ -113,6 +113,7 @@ public class PTableImpl implements PTable {
     private Short viewIndexId;
     private int estimatedSize;
     private List<byte[]> guidePosts = Collections.emptyList();
+    private PTableStats tableStats = PTableStats.EMPTY_STATS;
     
     public PTableImpl() {
         this.indexes = Collections.emptyList();
@@ -172,28 +173,33 @@ public class PTableImpl implements PTable {
         return new PTableImpl(
                 table.getTenantId(), table.getSchemaName(), table.getTableName(), table.getType(), table.getIndexState(), timeStamp, 
                 table.getSequenceNumber() + 1, table.getPKName(), table.getBucketNum(), getColumnsToClone(table), table.getParentTableName(), indexes,
-                table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(), table.isWALDisabled(), table.isMultiTenant(), table.getViewType(), table.getViewIndexId());
+                table.isImmutableRows(), table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(), table.isWALDisabled(),
+                table.isMultiTenant(), table.getViewType(), table.getViewIndexId(), table.getTableStats());
     }
 
     public static PTableImpl makePTable(PTable table, List<PColumn> columns) throws SQLException {
         return new PTableImpl(
                 table.getTenantId(), table.getSchemaName(), table.getTableName(), table.getType(), table.getIndexState(), table.getTimeStamp(), 
                 table.getSequenceNumber(), table.getPKName(), table.getBucketNum(), columns, table.getParentTableName(), table.getIndexes(), table.isImmutableRows(),
-                table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(), table.isWALDisabled(), table.isMultiTenant(), table.getViewType(), table.getViewIndexId());
+                table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(), table.isWALDisabled(), table.isMultiTenant(), table.getViewType(),
+                table.getViewIndexId(), table.getTableStats());
+
     }
 
     public static PTableImpl makePTable(PTable table, long timeStamp, long sequenceNumber, List<PColumn> columns) throws SQLException {
         return new PTableImpl(
                 table.getTenantId(), table.getSchemaName(), table.getTableName(), table.getType(), table.getIndexState(), timeStamp, 
                 sequenceNumber, table.getPKName(), table.getBucketNum(), columns, table.getParentTableName(), table.getIndexes(), table.isImmutableRows(),
-                table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(), table.isWALDisabled(), table.isMultiTenant(), table.getViewType(), table.getViewIndexId());
+                table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(), table.isWALDisabled(), table.isMultiTenant(),
+                table.getViewType(), table.getViewIndexId(), table.getTableStats());
     }
 
     public static PTableImpl makePTable(PTable table, long timeStamp, long sequenceNumber, List<PColumn> columns, boolean isImmutableRows) throws SQLException {
         return new PTableImpl(
                 table.getTenantId(), table.getSchemaName(), table.getTableName(), table.getType(), table.getIndexState(), timeStamp, 
                 sequenceNumber, table.getPKName(), table.getBucketNum(), columns, table.getParentTableName(), table.getIndexes(),
-                isImmutableRows, table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(), table.isWALDisabled(), table.isMultiTenant(), table.getViewType(), table.getViewIndexId());
+                isImmutableRows, table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(), table.isWALDisabled(),
+                table.isMultiTenant(), table.getViewType(), table.getViewIndexId(), table.getTableStats());
     }
 
     public static PTableImpl makePTable(PTable table, PIndexState state) throws SQLException {
@@ -201,14 +207,16 @@ public class PTableImpl implements PTable {
                 table.getTenantId(), table.getSchemaName(), table.getTableName(), table.getType(), state, table.getTimeStamp(), 
                 table.getSequenceNumber(), table.getPKName(), table.getBucketNum(), getColumnsToClone(table), 
                 table.getParentTableName(), table.getIndexes(), table.isImmutableRows(),
-                table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(), table.isWALDisabled(), table.isMultiTenant(), table.getViewType(), table.getViewIndexId());
+                table.getPhysicalNames(), table.getDefaultFamilyName(), table.getViewStatement(), table.isWALDisabled(),
+                table.isMultiTenant(), table.getViewType(), table.getViewIndexId(), table.getTableStats());
     }
 
     public static PTableImpl makePTable(PName tenantId, PName schemaName, PName tableName, PTableType type, PIndexState state, long timeStamp, long sequenceNumber,
             PName pkName, Integer bucketNum, List<PColumn> columns, PName dataTableName, List<PTable> indexes, boolean isImmutableRows,
             List<PName> physicalNames, PName defaultFamilyName, String viewExpression, boolean disableWAL, boolean multiTenant, ViewType viewType, Short viewIndexId) throws SQLException {
         return new PTableImpl(tenantId, schemaName, tableName, type, state, timeStamp, sequenceNumber, pkName, bucketNum, columns, dataTableName,
-                indexes, isImmutableRows, physicalNames, defaultFamilyName, viewExpression, disableWAL, multiTenant, viewType, viewIndexId);
+                indexes, isImmutableRows, physicalNames, defaultFamilyName, viewExpression, disableWAL, multiTenant, viewType, viewIndexId,
+                PTableStats.EMPTY_STATS);
     }
     
     public static PTableImpl makePTable(PName tenantId, PName schemaName, PName tableName, PTableType type,
@@ -222,13 +230,6 @@ public class PTableImpl implements PTable {
                 viewExpression, disableWAL, multiTenant, viewType, viewIndexId, stats);
     }
 
-    private PTableImpl(PName tenantId, PName schemaName, PName tableName, PTableType type, PIndexState state, long timeStamp, long sequenceNumber,
-            PName pkName, Integer bucketNum, List<PColumn> columns, PName dataTableName, List<PTable> indexes, boolean isImmutableRows,
-            List<PName> physicalNames, PName defaultFamilyName, String viewExpression, boolean disableWAL, boolean multiTenant, ViewType viewType, Short viewIndexId) throws SQLException {
-        init(tenantId, schemaName, tableName, type, state, timeStamp, sequenceNumber, pkName, bucketNum, columns,
-                new PTableStatsImpl(), dataTableName, indexes, isImmutableRows, physicalNames, defaultFamilyName, viewExpression, disableWAL, multiTenant, viewType, viewIndexId);
-    }
-    
     private PTableImpl(PName tenantId, PName schemaName, PName tableName, PTableType type, PIndexState state,
             long timeStamp, long sequenceNumber, PName pkName, Integer bucketNum, List<PColumn> columns,
             PName dataTableName, List<PTable> indexes, boolean isImmutableRows, List<PName> physicalNames,
@@ -285,6 +286,8 @@ public class PTableImpl implements PTable {
         this.multiTenant = multiTenant;
         this.viewType = viewType;
         this.viewIndexId = viewIndexId;
+
+        this.tableStats = stats;
         List<PColumn> pkColumns;
         PColumn[] allColumns;
 
@@ -362,7 +365,6 @@ public class PTableImpl implements PTable {
                 if (stats.getGuidePosts().get(defaultFamilyNameBytes) != null) {
                     guidePosts = stats.getGuidePosts().get(defaultFamilyNameBytes);
                     if (guidePosts != null) {
-                        Collections.sort(guidePosts, Bytes.BYTES_COMPARATOR);
                         estimatedSize += SizedUtil.sizeOfArrayList(guidePosts.size());
                         for (byte[] gps : guidePosts) {
                             estimatedSize += gps.length;
@@ -774,17 +776,8 @@ public class PTableImpl implements PTable {
             indexes.add(index);
         }
         boolean isImmutableRows = input.readBoolean();
-        TreeMap<byte[], List<byte[]>> guidePosts = new TreeMap<byte[], List<byte[]>>(Bytes.BYTES_COMPARATOR);
-        int size = WritableUtils.readVInt(input);
-        for (int i = 0; i < size; i++) {
-            byte[] key = Bytes.readByteArray(input);
-            int valueSize = WritableUtils.readVInt(input);
-            List<byte[]> value = Lists.newArrayListWithExpectedSize(valueSize);
-            for (int j = 0; j < valueSize; j++) {
-                value.add(j, Bytes.readByteArray(input));
-            }
-            guidePosts.put(key, value);
-        }
+        PTableStats stats = new PTableStatsImpl();
+        stats.readFields(input);
         byte[] dataTableNameBytes = Bytes.readByteArray(input);
         PName dataTableName = dataTableNameBytes.length == 0 ? null : PNameFactory.newName(dataTableNameBytes);
         byte[] defaultFamilyNameBytes = Bytes.readByteArray(input);
@@ -807,7 +800,6 @@ public class PTableImpl implements PTable {
                 physicalNames.add(PNameFactory.newName(physicalNameBytes));
             }
         }
-        PTableStats stats = new PTableStatsImpl(guidePosts);
         try {
             init(tenantId, schemaName, tableName, tableType, indexState, timeStamp, sequenceNumber,
                  pkName, bucketNum.equals(NO_SALTING) ? null : bucketNum, columns, stats,
@@ -993,5 +985,10 @@ public class PTableImpl implements PTable {
     public PTableKey getKey() {
         return key;
     }
+
+    @Override
+    public PTableStats getTableStats() {
+        return tableStats;
+    }
     
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/951cae0f/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStats.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStats.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStats.java
index be6cfd2..6e822c8 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStats.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStats.java
@@ -17,11 +17,17 @@
  */
 package org.apache.phoenix.schema.stat;
 
+import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.IOException;
 import java.util.List;
 import java.util.TreeMap;
 
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.io.Writable;
+
+import com.google.common.collect.Maps;
+
 
 /**
  * Interface for Phoenix table statistics. Statistics is collected on the server
@@ -30,16 +36,28 @@ import java.util.TreeMap;
  * The table is defined on the client side, but it is populated on the server side. The client
  * should not populate any data to the statistics object.
  */
-public interface PTableStats {
+public interface PTableStats extends Writable {
+
+    public static final PTableStats EMPTY_STATS = new PTableStats() {
+        private final TreeMap<byte[], List<byte[]>> EMPTY_TREE_MAP = Maps.newTreeMap(Bytes.BYTES_COMPARATOR);
+        @Override
+        public TreeMap<byte[], List<byte[]>> getGuidePosts() {
+            return EMPTY_TREE_MAP;
+        }
+
+        @Override
+        public void write(DataOutput output) throws IOException {
+        }
+
+        @Override
+        public void readFields(DataInput arg0) throws IOException {
+        }
+    };
 
     /**
-     * Given the region info, returns an array of bytes that is the current estimate of key
-     * distribution inside that region. The keys should split that region into equal chunks.
-     * 
-     * @param region
-     * @return array of keys
+     * TODO: Change from TreeMap to Map
+     * Returns a tree map of the guide posts collected against a column family
+     * @return
      */
     TreeMap<byte[], List<byte[]>> getGuidePosts();
-
-    void write(DataOutput output) throws IOException;
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/951cae0f/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStatsImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStatsImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStatsImpl.java
index 88ce1fb..36b732a 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStatsImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStatsImpl.java
@@ -17,6 +17,7 @@
  */
 package org.apache.phoenix.schema.stat;
 
+import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.IOException;
 import java.util.List;
@@ -26,17 +27,14 @@ import java.util.TreeMap;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.io.WritableUtils;
 
+import com.google.common.collect.Lists;
+
 
 /**
  * Implementation for PTableStats.
  */
 public class PTableStatsImpl implements PTableStats {
-
-    // The map for guide posts should be immutable. We only take the current snapshot from outside
-    // method call and store it.
-    
-    public static final PTableStats NO_STATS = new PTableStatsImpl();
-    private TreeMap<byte[], List<byte[]>> guidePosts = new TreeMap<byte[], List<byte[]>>(Bytes.BYTES_COMPARATOR);
+    private final TreeMap<byte[], List<byte[]>> guidePosts;
 
     public PTableStatsImpl() {
         this(new TreeMap<byte[], List<byte[]>>(Bytes.BYTES_COMPARATOR));
@@ -67,4 +65,18 @@ public class PTableStatsImpl implements PTableStats {
             }
         }
     }
+
+    @Override
+    public void readFields(DataInput input) throws IOException {
+        int size = WritableUtils.readVInt(input);
+        for (int i = 0; i < size; i++) {
+            byte[] key = Bytes.readByteArray(input);
+            int valueSize = WritableUtils.readVInt(input);
+            List<byte[]> value = Lists.newArrayListWithExpectedSize(valueSize);
+            for (int j = 0; j < valueSize; j++) {
+                value.add(j, Bytes.readByteArray(input));
+            }
+            guidePosts.put(key, value);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/951cae0f/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/StatisticsCollectionScope.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/StatisticsCollectionScope.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/StatisticsCollectionScope.java
new file mode 100644
index 0000000..8a020d2
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/StatisticsCollectionScope.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you maynot 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 applicablelaw 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.
+ */
+package org.apache.phoenix.schema.stat;
+
+public enum StatisticsCollectionScope {
+    COLUMNS, INDEX, ALL;
+
+    public static StatisticsCollectionScope getDefault() {
+        return ALL;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/951cae0f/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/StatisticsUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/StatisticsUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/StatisticsUtil.java
index 2086d31..a397a19 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/StatisticsUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/StatisticsUtil.java
@@ -106,6 +106,6 @@ public class StatisticsUtil {
         } finally {
             scanner.close();
         }
-        return PTableStatsImpl.NO_STATS;
+        return PTableStats.EMPTY_STATS;
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/951cae0f/phoenix-core/src/test/java/org/apache/phoenix/util/TestUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/util/TestUtil.java b/phoenix-core/src/test/java/org/apache/phoenix/util/TestUtil.java
index 3cf90fe..b832c72 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/util/TestUtil.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/util/TestUtil.java
@@ -461,7 +461,7 @@ public class TestUtil {
                     " WHERE " + ((lowerRange != null ? (pkCol + " >= ? " + (upperRange != null ? " AND " : "")) : "") 
                               + (upperRange != null ? (pkCol + " < ?") : "" )));
         String whereClause = whereClauseSuffix == null ? whereClauseStart : whereClauseStart.length() == 0 ? (" WHERE " + whereClauseSuffix) : (" AND " + whereClauseSuffix);
-        String query = "SELECT COUNT(*) FROM " + tableName + whereClause;
+        String query = "SELECT /*+ NO_INDEX */ COUNT(*) FROM " + tableName + whereClause;
         PhoenixPreparedStatement pstmt = conn.prepareStatement(query).unwrap(PhoenixPreparedStatement.class);
         if (lowerRange != null) {
             pstmt.setBytes(1, lowerRange);
@@ -483,12 +483,22 @@ public class TestUtil {
     }
 
     public static void analyzeTable(Connection conn, String tableName) throws IOException, SQLException {
-        String query = "ANALYZE " + tableName;
+        String query = "UPDATE STATISTICS " + tableName;
+        conn.createStatement().execute(query);
+    }
+    
+    public static void analyzeTableIndex(Connection conn, String tableName) throws IOException, SQLException {
+        String query = "UPDATE STATISTICS " + tableName+ " INDEX";
+        conn.createStatement().execute(query);
+    }
+    
+    public static void analyzeTableColumns(Connection conn) throws IOException, SQLException {
+        String query = "UPDATE STATISTICS " + STABLE_NAME+ " COLUMNS";
         conn.createStatement().execute(query);
     }
     
     public static void analyzeTable(Connection conn) throws IOException, SQLException {
-        String query = "ANALYZE " + STABLE_NAME;
+        String query = "UPDATE STATISTICS " + STABLE_NAME;
         conn.createStatement().execute(query);
     }
     


[2/2] git commit: Move EMPTY_STATS impl to interface singleton

Posted by ja...@apache.org.
Move EMPTY_STATS impl to interface singleton


Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/836140b9
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/836140b9
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/836140b9

Branch: refs/heads/3.0
Commit: 836140b937058f1bbfd9a7d6129aaad0c82eb4b4
Parents: 951cae0
Author: James Taylor <jt...@salesforce.com>
Authored: Wed Oct 8 17:07:29 2014 -0700
Committer: James Taylor <jt...@salesforce.com>
Committed: Wed Oct 8 17:07:29 2014 -0700

----------------------------------------------------------------------
 .../phoenix/schema/PColumnFamilyImpl.java       | 11 +++---
 .../org/apache/phoenix/schema/PTableImpl.java   | 41 +++++---------------
 .../apache/phoenix/schema/stat/PTableStats.java | 15 +++----
 .../phoenix/schema/stat/PTableStatsImpl.java    | 11 ++----
 4 files changed, 26 insertions(+), 52 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/phoenix/blob/836140b9/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnFamilyImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnFamilyImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnFamilyImpl.java
index 15ac8fa..9841233 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnFamilyImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PColumnFamilyImpl.java
@@ -49,17 +49,16 @@ public class PColumnFamilyImpl implements PColumnFamily {
     public PColumnFamilyImpl(PName name, List<PColumn> columns, List<byte[]> guidePosts) {
         Preconditions.checkNotNull(name);
         // Include guidePosts also in estimating the size
-        int guidePostsSize = 0;
+        long estimatedSize = SizedUtil.OBJECT_SIZE + SizedUtil.POINTER_SIZE * 5 + SizedUtil.INT_SIZE + name.getEstimatedSize() +
+                SizedUtil.sizeOfMap(columns.size()) * 2 + SizedUtil.sizeOfArrayList(columns.size());
         if(guidePosts != null) {
-            guidePostsSize = guidePosts.size();
+            int guidePostsSize = guidePosts.size();
+            estimatedSize += SizedUtil.sizeOfArrayList(guidePostsSize);
             for(byte[] gps : guidePosts) {
-                guidePostsSize += gps.length;
+                estimatedSize += gps.length;
             }
-            Collections.sort(guidePosts, Bytes.BYTES_COMPARATOR);
             this.guidePosts = guidePosts;
         }
-        long estimatedSize = SizedUtil.OBJECT_SIZE + SizedUtil.POINTER_SIZE * 5 + SizedUtil.INT_SIZE + name.getEstimatedSize() +
-                SizedUtil.sizeOfMap(columns.size()) * 2 + SizedUtil.sizeOfArrayList(columns.size()) + SizedUtil.sizeOfArrayList(guidePostsSize);
         this.name = name;
         this.columns = ImmutableList.copyOf(columns);
         ImmutableMap.Builder<String, PColumn> columnByStringBuilder = ImmutableMap.builder();

http://git-wip-us.apache.org/repos/asf/phoenix/blob/836140b9/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
index c909345..a50c0e3 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
@@ -31,7 +31,6 @@ import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.TreeMap;
 
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.KeyValue;
@@ -355,33 +354,22 @@ public class PTableImpl implements PTable {
         Iterator<Map.Entry<PName,List<PColumn>>> iterator = familyMap.entrySet().iterator();
         PColumnFamily[] families = new PColumnFamily[familyMap.size()];
         if (families.length == 0) {
-            if(stats != null) {
-                byte[] defaultFamilyNameBytes = null;
-                if(defaultFamilyName == null) {
-                    defaultFamilyNameBytes = QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES;
-                } else {
-                    defaultFamilyNameBytes = defaultFamilyName.getBytes();
-                }
-                if (stats.getGuidePosts().get(defaultFamilyNameBytes) != null) {
-                    guidePosts = stats.getGuidePosts().get(defaultFamilyNameBytes);
-                    if (guidePosts != null) {
-                        estimatedSize += SizedUtil.sizeOfArrayList(guidePosts.size());
-                        for (byte[] gps : guidePosts) {
-                            estimatedSize += gps.length;
-                        }
-                    }
+            byte[] defaultFamilyNameBytes = (defaultFamilyName == null) ? QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES : defaultFamilyName.getBytes();
+            List<byte[]> guidePosts = stats.getGuidePosts().get(defaultFamilyNameBytes);
+            if (guidePosts != null) {
+                this.guidePosts = guidePosts;
+                estimatedSize += SizedUtil.sizeOfArrayList(guidePosts.size());
+                for (byte[] gps : guidePosts) {
+                    estimatedSize += gps.length;
                 }
             }
         }
         ImmutableMap.Builder<String, PColumnFamily> familyByString = ImmutableMap.builder();
         ImmutableSortedMap.Builder<byte[], PColumnFamily> familyByBytes = ImmutableSortedMap
                 .orderedBy(Bytes.BYTES_COMPARATOR);
-        List<byte[]> famGuidePosts = null;
         for (int i = 0; i < families.length; i++) {
             Map.Entry<PName,List<PColumn>> entry = iterator.next();
-            if (stats != null) {
-                famGuidePosts = stats.getGuidePosts().get(entry.getKey().getBytes());
-            }
+            List<byte[]> famGuidePosts = stats.getGuidePosts().get(entry.getKey().getBytes());
             PColumnFamily family = new PColumnFamilyImpl(entry.getKey(), entry.getValue(), famGuidePosts);
             families[i] = family;
             familyByString.put(family.getName().getString(), family);
@@ -843,18 +831,7 @@ public class PTableImpl implements PTable {
             index.write(output);
         }
         output.writeBoolean(isImmutableRows);
-        TreeMap<byte[], List<byte[]>> guidePosts = new TreeMap<byte[], List<byte[]>>(Bytes.BYTES_COMPARATOR);
-        if(this.families.size() == 0) {
-            byte[] fam = (defaultFamilyName == null ? QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES : defaultFamilyName.getBytes());
-            guidePosts.put(fam, this.guidePosts);
-        } else {
-            // Get the stats from the PColumnFamily
-            for(PColumnFamily fam : families) {
-                guidePosts.put(fam.getName().getBytes(), fam.getGuidePosts());
-            }
-        }
-        PTableStats stats = new PTableStatsImpl(guidePosts);
-        stats.write(output);
+        tableStats.write(output);
         Bytes.writeByteArray(output, parentTableName == null ? ByteUtil.EMPTY_BYTE_ARRAY : parentTableName.getBytes());
         Bytes.writeByteArray(output, defaultFamilyName == null ? ByteUtil.EMPTY_BYTE_ARRAY : defaultFamilyName.getBytes());
         output.writeBoolean(disableWAL);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/836140b9/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStats.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStats.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStats.java
index 6e822c8..cce911a 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStats.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStats.java
@@ -21,12 +21,12 @@ import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.IOException;
 import java.util.List;
-import java.util.TreeMap;
+import java.util.SortedMap;
 
-import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.io.Writable;
+import org.apache.hadoop.io.WritableUtils;
 
-import com.google.common.collect.Maps;
+import com.google.common.collect.ImmutableSortedMap;
 
 
 /**
@@ -39,18 +39,19 @@ import com.google.common.collect.Maps;
 public interface PTableStats extends Writable {
 
     public static final PTableStats EMPTY_STATS = new PTableStats() {
-        private final TreeMap<byte[], List<byte[]>> EMPTY_TREE_MAP = Maps.newTreeMap(Bytes.BYTES_COMPARATOR);
         @Override
-        public TreeMap<byte[], List<byte[]>> getGuidePosts() {
-            return EMPTY_TREE_MAP;
+        public SortedMap<byte[], List<byte[]>> getGuidePosts() {
+            return ImmutableSortedMap.of();
         }
 
         @Override
         public void write(DataOutput output) throws IOException {
+            WritableUtils.writeVInt(output, 0);
         }
 
         @Override
         public void readFields(DataInput arg0) throws IOException {
+            throw new UnsupportedOperationException();
         }
     };
 
@@ -59,5 +60,5 @@ public interface PTableStats extends Writable {
      * Returns a tree map of the guide posts collected against a column family
      * @return
      */
-    TreeMap<byte[], List<byte[]>> getGuidePosts();
+    SortedMap<byte[], List<byte[]>> getGuidePosts();
 }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/836140b9/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStatsImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStatsImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStatsImpl.java
index 36b732a..814d1a9 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStatsImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStatsImpl.java
@@ -22,6 +22,7 @@ import java.io.DataOutput;
 import java.io.IOException;
 import java.util.List;
 import java.util.Map.Entry;
+import java.util.SortedMap;
 import java.util.TreeMap;
 
 import org.apache.hadoop.hbase.util.Bytes;
@@ -34,27 +35,23 @@ import com.google.common.collect.Lists;
  * Implementation for PTableStats.
  */
 public class PTableStatsImpl implements PTableStats {
-    private final TreeMap<byte[], List<byte[]>> guidePosts;
+    private final SortedMap<byte[], List<byte[]>> guidePosts;
 
     public PTableStatsImpl() {
         this(new TreeMap<byte[], List<byte[]>>(Bytes.BYTES_COMPARATOR));
     }
 
-    public PTableStatsImpl(TreeMap<byte[], List<byte[]>> guidePosts) {
+    public PTableStatsImpl(SortedMap<byte[], List<byte[]>> guidePosts) {
         this.guidePosts = guidePosts;
     }
     
     @Override
-    public TreeMap<byte[], List<byte[]>> getGuidePosts() {
+    public SortedMap<byte[], List<byte[]>> getGuidePosts() {
         return guidePosts;
     }
 
     @Override
     public void write(DataOutput output) throws IOException {
-        if (guidePosts == null) {
-            WritableUtils.writeVInt(output, 0);
-            return;
-        }
         WritableUtils.writeVInt(output, guidePosts.size());
         for (Entry<byte[], List<byte[]>> entry : guidePosts.entrySet()) {
             Bytes.writeByteArray(output, entry.getKey());