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 <jtay...@salesforce.com> Authored: Wed Oct 8 12:21:06 2014 -0700 Committer: James Taylor <jtay...@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); }