zoukankan      html  css  js  c++  java
  • [saiku] 优化多维度查询效率

    1、优化查询精度

    优化原因:当维度过多时,查询很复杂,效率较慢。因此看能否通过优化sql的方式来提高查询效率。

    代码跟踪查看(维度多余3时查询条件里面有in,优化不用in关键字)

        public abstract class AbstractQuerySpec implements QuerySpec {
                protected Map<String, String> nonDistinctGenerateSql(SqlQuery sqlQuery){
                    String expr = column.generateExprString(sqlQuery);
    
                    StarColumnPredicate predicate = getColumnPredicate(i);
                    final String where = RolapStar.Column.createInExpr(
                        expr,
                        predicate,
                        column.getDatatype(),
                        sqlQuery);
                    if (!where.equals("true")) {
                        sqlQuery.addWhere(where);
                    }
    public class Aggregation {                
    createSegments{
         new Segment(
        star,
        constrainedColumnsBitKey,
        columns,
        measure,
        predicates,//这里 : [true, true, true, F_JCJY_CODE_SSQ.SFDM={230000, 370000}] 当为具体数值不为true时使用了in(230000,370000)
        Collections.<Segment.ExcludedRegion>emptyList(),compoundPredicateList);
    }
    private StarColumnPredicate[] initPredicates() {
        StarColumnPredicate[] predicates =
            new StarColumnPredicate[columns.length];
        for (int j = 0; j < columns.length; j++) {
            Set<StarColumnPredicate> valueSet = valueSets[j];
    
            StarColumnPredicate predicate;
            if (valueSet == null) {
                predicate = LiteralStarPredicate.FALSE;
            } else {
                ValueColumnPredicate[] values =
                    valueSet.toArray(
                        new ValueColumnPredicate[valueSet.size()]);
                // Sort array to achieve determinism in generated SQL.
                Arrays.sort(
                    values,
                    ValueColumnConstraintComparator.instance);
    
                predicate =
                    new ListColumnPredicate(
                        columns[j],
                        Arrays.asList((StarColumnPredicate[]) values));
            }
    
            predicates[j] = predicate;
        }
        return predicates;
    }
    AggregationManager.loadAggregation(
    cacheMgr,
    cellRequestCount,
    measuresList,
    columns,
    batchKey,
    predicates,
    groupingSetsCollector,
    segmentFutures);
    predicates = aggregation.optimizePredicates(columns, predicates);
    public StarColumnPredicate[] optimizePredicates(
        RolapStar.Column[] columns,
        StarColumnPredicate[] predicates)
    {    

    跟踪到最后,来到下面的代码处

    if (MondrianProperties.instance().OptimizePredicates.get() || bloats[j] == 1){
        newPredicates[j] = new LiteralStarPredicate(columns[j], true);//设置为ture
    }

    第一个条件

    MondrianProperties.instance().OptimizePredicates.get()
    
    配置mondrian.properties里面的(默认也是true)
    mondrian.rolap.aggregates.optimizePredicates=true

    第二个条件

    bloats[j] == 1
    
    mondrian包里面的Aggregation类的optimizePredicates方法修改如下:
    
    if (valueCount < 2) {
        bloats[i] = 1.0;//原来是0.0
        continue;
    }
    
    if (valueCount > maxConstraints) {           
        bloats[i] = 1.0;
        continue;
    }
    
    而 maxConstraints 是在 mondrian。properties里面配置的。
    默认是:1000,表示如果in里面的值小于1000个时,采用in精细化查询,否则不带in查询语句。这里我们配置为1.
    
    mondrian.rolap.maxConstraints=1

    总结:需要修改的地方如下:

    #Aggregation类
    if (valueCount < 2) {
        bloats[i] = 1.0;//原来是0.0
        continue;
    }
    
    #mondrian.properties配置文件
    mondrian.rolap.maxConstraints=1
    mondrian.rolap.aggregates.optimizePredicates=true

    注意:后来发现,查询效率慢主要是因为查询出的结果需要经过一系列的矩阵变换计算和递归计算,是作为数据的后处理操作。

    如果报出内存溢出,请增大应用内存。

    2、缓存结果

    查询后将结果缓存,以便第二次查询时提高查询效率

    配置mondrian.properties

    //开启聚合表功能
    mondrian.rolap.aggregates.ChooseByVolume=true
    mondrian.rolap.aggregates.Read=true
    mondrian.rolap.aggregates.Use=true
    //缓存结果集
    mondrian.rolap.cellBatchSize=0
    mondrian.rolap.star.disableCaching=false
    mondrian.expCache.enable=true
    mondrian.rolap.EnableRolapCubeMemberCache=true
    mondrian.result.highCardChunkSize=50
    mondrian.rolap.evaluate.MaxEvalDepth=1

    //允许监控内存、显示维度前缀、空值处理
    mondrian.util.memoryMonitor.enable
    =true
    mondrian.olap.elements.NeedDimensionPrefix=true
    mondrian.olap.NullMemberRepresentation=u7a7a
    //sql处理
    mondrian.rolap.generate.formatted.sql=true
    mondrian.rolap.maxSqlThreads=1000

    3、其他方式

    (1)使用聚合表

    聚合表是数据仓库中包含事实数据的汇总信息的表

    (2)建立物化视图

    将查询的结果集先通过建立视图,定时跑批数据到视图中,直接查询视图得到结果,避免了查询时去计算。
    简化计算和查询过程。

    (3)退化维度

    如果一个维度有很多可能,如学校作为维度有很多值。
    这时候不再使用学校ID和表关联,而是直接将学校名称写到和他关联的表里面去。
    这样就相当于少关联一张表,加快查询的效率。
  • 相关阅读:
    *** 实现冒泡排序模板
    *** 实现stack模板
    python uses xml
    [转]给未来的电子通信工程师
    *** strRevert.cpp
    *** strlen.cpp
    *** checkRevStr.cpp 查看字符串是否是回文
    *** 自己代码:实现字符串比较
    *** 自写代码:查找两个字符串的最大公共子串
    *** 自写代码:在字符串中插入连续字符的个数
  • 原文地址:https://www.cnblogs.com/avivaye/p/5250474.html
Copyright © 2011-2022 走看看