Search in sources :

Example 1 with RectangularCellSetFormatter

use of org.olap4j.layout.RectangularCellSetFormatter in project mondrian by pentaho.

the class MonitorTest method testMe.

/**
 * Exercises as many fields of the monitoring stats classes as possible.
 * So that we can check that they are being populated.
 */
public void testMe() throws SQLException {
    String queryString = "WITH MEMBER [Measures].[Foo] AS\n" + " [Measures].[Unit Sales]" + " + case when [Measures].[Unit Sales] > 0\n" + "   then CInt( ([Measures].[Foo], [Time].PrevMember) )\n" + "   end\n" + "SELECT [Measures].[Foo] on 0\n" + "from [Sales]\n" + "where [Time].[1997].[Q3].[9]";
    final OlapStatement statement1 = getTestContext().getOlap4jConnection().createStatement();
    CellSet cellSet = statement1.executeOlapQuery(queryString);
    StringWriter stringWriter = new StringWriter();
    new RectangularCellSetFormatter(true).format(cellSet, new PrintWriter(stringWriter));
    statement1.close();
    println(stringWriter);
    final MondrianServer mondrianServer = MondrianServer.forConnection(getConnection());
    final Monitor monitor = mondrianServer.getMonitor();
    final ServerInfo server = monitor.getServer();
    println("# stmts open: " + server.getStatementCurrentlyOpenCount());
    println("# connections open: " + server.getConnectionCurrentlyOpenCount());
    println("# rows fetched: " + server.sqlStatementRowFetchCount);
    println("# sql stmts open: " + server.getSqlStatementCurrentlyOpenCount());
    // # sql stmts by category (cell query, member query, other)
    // -- if you want to do this, capture sql statement events
    // cell cache requests
    // cell cache misses
    // cell cache hits
    final List<ConnectionInfo> connections = monitor.getConnections();
    ConnectionInfo lastConnection = connections.get(connections.size() - 1);
    // Cannot reliably retrieve the last statement, since statements are
    // removed from the map on completion.
    // final List<StatementInfo> statements = monitor.getStatements();
    // StatementInfo lastStatement = statements.get(statements.size() - 1);
    println("# cell cache requests, misses, hits; " + "by server, connection, mdx statement: " + server.cellCacheRequestCount + ", " + server.getCellCacheMissCount() + ", " + server.cellCacheHitCount + "; " + lastConnection.cellCacheRequestCount + ", " + (lastConnection.cellCacheRequestCount - lastConnection.cellCacheHitCount) + ", " + lastConnection.cellCacheHitCount);
    // cache misses in the last minute
    // cache hits in the last minute
    // -- build a layer on top of monitor that polls say every 15 seconds,
    // and keeps results for a few minutes
    println("number of mdx statements currently open: " + server.getStatementCurrentlyOpenCount());
    println("number of mdx statements currently executing: " + server.getStatementCurrentlyExecutingCount());
    println("jvm memory: " + server.jvmHeapBytesUsed + ", max: " + server.jvmHeapBytesMax + ", committed: " + server.jvmHeapBytesCommitted);
    println("number of segments: " + server.segmentCount + ", ever created: " + server.segmentCreateCount + ", number of cells: " + server.cellCount + ", number of cell coordinates: " + server.cellCoordinateCount + ", average cell dimensionality: " + ((float) server.cellCoordinateCount / (float) server.cellCount));
    println("Connection: " + lastConnection);
    println("Server: " + server);
// number of mdx function calls cumulative
// how many operations have been evaluated in sql?
// number of members in cache
// number of cells in segments
// mdx query time
// sql query time
// sql rows
// olap4j connection pool size
// sql connection pool size
// thread count
// # schemas in schema cache
// cells fulfilled by sql statements
// mondrian server count (other stats relate to just one server)
// 
// Events:
// 
// SQL statement start
// SQL statment stop
// external cache call
// sort
// (other expensive operations similar to sort?)
}
Also used : OlapStatement(org.olap4j.OlapStatement) MondrianServer(mondrian.olap.MondrianServer) StringWriter(java.io.StringWriter) RectangularCellSetFormatter(org.olap4j.layout.RectangularCellSetFormatter) CellSet(org.olap4j.CellSet) PrintWriter(java.io.PrintWriter)

Example 2 with RectangularCellSetFormatter

use of org.olap4j.layout.RectangularCellSetFormatter in project mondrian by pentaho.

the class BasicQueryTest method testExplainComplex.

public void testExplainComplex() throws SQLException {
    OlapConnection connection = TestContext.instance().getOlap4jConnection();
    final OlapStatement statement = connection.createStatement();
    final String mdx = "with member [Time].[Time].[1997].[H1] as\n" + "    Aggregate({[Time].[1997].[Q1], [Time].[1997].[Q2]})\n" + "  member [Measures].[Store Margin] as\n" + "    [Measures].[Store Sales] - [Measures].[Store Cost],\n" + "      format_string =\n" + "        iif(\n" + "          [Measures].[Unit Sales] > 50000,\n" + "          \"\\<b\\>#.00\\<\\/b\\>\",\n" + "           \"\\<i\\>#.00\\<\\/i\\>\")\n" + "  set [Hi Val Products] as\n" + "    Filter(\n" + "      Descendants([Product].[Drink], , LEAVES),\n" + "     [Measures].[Unit Sales] > 100)\n" + "select\n" + "  {[Measures].[Unit Sales], [Measures].[Store Margin]} on 0,\n" + "  [Hi Val Products] * [Marital Status].Members on 1\n" + "from [Sales]\n" + "where [Gender].[F]";
    // Plan before execution.
    final ResultSet resultSet = statement.executeQuery("explain plan for\n" + mdx);
    assertTrue(resultSet.next());
    String s = resultSet.getString(1);
    TestContext.assertStubbedEqualsVerbose("Axis (FILTER):\n" + "SetListCalc(name=SetListCalc, class=class mondrian.olap.fun.SetFunDef$SetListCalc, type=SetType<MemberType<member=[Gender].[F]>>, resultStyle=MUTABLE_LIST)\n" + "    ()(name=(), class=class mondrian.olap.fun.SetFunDef$SetListCalc$2, type=MemberType<member=[Gender].[F]>, resultStyle=VALUE)\n" + "        Literal(name=Literal, class=class mondrian.calc.impl.ConstantCalc, type=MemberType<member=[Gender].[F]>, resultStyle=VALUE_NOT_NULL, value=[Gender].[F])\n" + "\n" + "Axis (COLUMNS):\n" + "SetListCalc(name=SetListCalc, class=class mondrian.olap.fun.SetFunDef$SetListCalc, type=SetType<MemberType<member=[Measures].[Unit Sales]>>, resultStyle=MUTABLE_LIST)\n" + "    2(name=2, class=class mondrian.olap.fun.SetFunDef$SetListCalc$2, type=MemberType<member=[Measures].[Unit Sales]>, resultStyle=VALUE)\n" + "        Literal(name=Literal, class=class mondrian.calc.impl.ConstantCalc, type=MemberType<member=[Measures].[Unit Sales]>, resultStyle=VALUE_NOT_NULL, value=[Measures].[Unit Sales])\n" + "    2(name=2, class=class mondrian.olap.fun.SetFunDef$SetListCalc$2, type=MemberType<member=[Measures].[Store Margin]>, resultStyle=VALUE)\n" + "        Literal(name=Literal, class=class mondrian.calc.impl.ConstantCalc, type=MemberType<member=[Measures].[Store Margin]>, resultStyle=VALUE_NOT_NULL, value=[Measures].[Store Margin])\n" + "\n" + "Axis (ROWS):\n" + "CrossJoinIterCalc(name=CrossJoinIterCalc, class=class mondrian.olap.fun.CrossJoinFunDef$CrossJoinIterCalc, type=SetType<TupleType<MemberType<member=[Product].[Drink]>, MemberType<hierarchy=[Marital Status]>>>, resultStyle=ITERABLE)\n" + "    1(name=1, class=class mondrian.mdx.NamedSetExpr$1, type=SetType<MemberType<member=[Product].[Drink]>>, resultStyle=ITERABLE)\n" + "    Members(name=Members, class=class mondrian.olap.fun.BuiltinFunTable$27$1, type=SetType<MemberType<hierarchy=[Marital Status]>>, resultStyle=MUTABLE_LIST)\n" + "        Literal(name=Literal, class=class mondrian.calc.impl.ConstantCalc, type=HierarchyType<hierarchy=[Marital Status]>, resultStyle=VALUE_NOT_NULL, value=[Marital Status])\n" + "\n", s);
    // Plan after execution, including profiling.
    final String[] strings = { null, null };
    ((mondrian.server.Statement) statement).enableProfiling(new ProfileHandler() {

        public void explain(String plan, QueryTiming timing) {
            strings[0] = plan;
            strings[1] = String.valueOf(timing);
        }
    });
    final CellSet cellSet = statement.executeOlapQuery(mdx);
    new RectangularCellSetFormatter(true).format(cellSet, new PrintWriter(new StringWriter()));
    cellSet.close();
    final String actual = strings[0].replaceAll("callMillis=[0-9]+", "callMillis=nnn").replaceAll("[0-9]+ms", "nnnms");
    TestContext.assertStubbedEqualsVerbose("Axis (FILTER):\n" + "SetListCalc(name=SetListCalc, class=class mondrian.olap.fun.SetFunDef$SetListCalc, type=SetType<MemberType<member=[Gender].[F]>>, resultStyle=MUTABLE_LIST, callCount=2, callMillis=nnn, elementCount=2, elementSquaredCount=2)\n" + "    ()(name=(), class=class mondrian.olap.fun.SetFunDef$SetListCalc$2, type=MemberType<member=[Gender].[F]>, resultStyle=VALUE)\n" + "        Literal(name=Literal, class=class mondrian.calc.impl.ConstantCalc, type=MemberType<member=[Gender].[F]>, resultStyle=VALUE_NOT_NULL, value=[Gender].[F], callCount=2, callMillis=nnn)\n" + "\n" + "Axis (COLUMNS):\n" + "SetListCalc(name=SetListCalc, class=class mondrian.olap.fun.SetFunDef$SetListCalc, type=SetType<MemberType<member=[Measures].[Unit Sales]>>, resultStyle=MUTABLE_LIST, callCount=2, callMillis=nnn, elementCount=4, elementSquaredCount=8)\n" + "    2(name=2, class=class mondrian.olap.fun.SetFunDef$SetListCalc$2, type=MemberType<member=[Measures].[Unit Sales]>, resultStyle=VALUE)\n" + "        Literal(name=Literal, class=class mondrian.calc.impl.ConstantCalc, type=MemberType<member=[Measures].[Unit Sales]>, resultStyle=VALUE_NOT_NULL, value=[Measures].[Unit Sales], callCount=2, callMillis=nnn)\n" + "    2(name=2, class=class mondrian.olap.fun.SetFunDef$SetListCalc$2, type=MemberType<member=[Measures].[Store Margin]>, resultStyle=VALUE)\n" + "        Literal(name=Literal, class=class mondrian.calc.impl.ConstantCalc, type=MemberType<member=[Measures].[Store Margin]>, resultStyle=VALUE_NOT_NULL, value=[Measures].[Store Margin], callCount=2, callMillis=nnn)\n" + "\n" + "Axis (ROWS):\n" + "CrossJoinIterCalc(name=CrossJoinIterCalc, class=class mondrian.olap.fun.CrossJoinFunDef$CrossJoinIterCalc, type=SetType<TupleType<MemberType<member=[Product].[Drink]>, MemberType<hierarchy=[Marital Status]>>>, resultStyle=ITERABLE, callCount=2, callMillis=nnn, elementCount=0, elementSquaredCount=0)\n" + "    1(name=1, class=class mondrian.mdx.NamedSetExpr$1, type=SetType<MemberType<member=[Product].[Drink]>>, resultStyle=ITERABLE)\n" + "    Members(name=Members, class=class mondrian.olap.fun.BuiltinFunTable$27$1, type=SetType<MemberType<hierarchy=[Marital Status]>>, resultStyle=MUTABLE_LIST)\n" + "        Literal(name=Literal, class=class mondrian.calc.impl.ConstantCalc, type=HierarchyType<hierarchy=[Marital Status]>, resultStyle=VALUE_NOT_NULL, value=[Marital Status], callCount=2, callMillis=nnn)\n" + "\n", actual);
    assertTrue(strings[1], strings[1].contains("SqlStatement-SqlTupleReader.readTuples [[Product].[Product " + "Category]] invoked 1 times for total of "));
}
Also used : RectangularCellSetFormatter(org.olap4j.layout.RectangularCellSetFormatter) StringWriter(java.io.StringWriter) PrintWriter(java.io.PrintWriter)

Aggregations

PrintWriter (java.io.PrintWriter)2 StringWriter (java.io.StringWriter)2 RectangularCellSetFormatter (org.olap4j.layout.RectangularCellSetFormatter)2 MondrianServer (mondrian.olap.MondrianServer)1 CellSet (org.olap4j.CellSet)1 OlapStatement (org.olap4j.OlapStatement)1