private boolean optimizeMapAggrGroupBy(String dest, QB qb) throws SemanticException {
    List<ASTNode> grpByExprs = getGroupByForClause(qb.getParseInfo(), dest);
    if ((grpByExprs != null) && !grpByExprs.isEmpty()) {
      return false;
    }

    return qb.getParseInfo().getDistinctFuncExprsForClause(dest).isEmpty();
  }
Generate a Group-By plan using a 2 map-reduce jobs (5 operators will be
inserted):

ReduceSink ( keys = (K1_EXP, K2_EXP, DISTINCT_EXP), values = (A1_EXP,
A2_EXP) ) NOTE: If DISTINCT_EXP is null, partition by rand() SortGroupBy
(keys = (KEY.0,KEY.1), aggregations = (count_distinct(KEY.2), sum(VALUE.0),
count(VALUE.1))) ReduceSink ( keys = (0,1), values=(2,3,4)) SortGroupBy
(keys = (KEY.0,KEY.1), aggregations = (sum(VALUE.0), sum(VALUE.1),
sum(VALUE.2))) Select (final selects).

@param dest
@param qb
@param input
@return
@throws SemanticException

          Generate a Group-By plan using a 2 map-reduce jobs. Spray by the
          grouping key and distinct key (or a random number, if no distinct
          is present) in hope of getting a uniform distribution, and
          compute partial aggregates grouped by the reduction key (grouping
          key + distinct key). Evaluate partial aggregates first, and spray
          by the grouping key to compute actual aggregates in the second
          phase. The aggregation evaluation functions are as follows:
          Partitioning Key: random() if no DISTINCT grouping + distinct key
          if DISTINCT

          Sorting Key: grouping key if no DISTINCT grouping + distinct key
          if DISTINCT

          Reducer: iterate/terminatePartial (mode = PARTIAL1)

          STAGE 2

          Partitioning Key: grouping key

          Sorting Key: grouping key if no DISTINCT grouping + distinct key
          if DISTINCT

          Reducer: merge/terminate (mode = FINAL)
ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java