优化group by ,group by导致sql性能下降

在优化如下sql的时候,并查看其执行计划,发现整体sql的性能主要卡在group by,应该如何优化?
具体执行计划如下:

--------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                 | Name               | Rows  | Bytes |TempSpc| Cost (%CPU)| Time       | Pstart| Pstop |
--------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                   |       |       |       |  3136M(100)|       |       |       |
|   1 |  HASH GROUP BY                 |                   |   188K|  6802K|    10M|  3136M  (1)|999:59:59 |       |       |

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|*  2 |   FILTER                 |                   |       |       |       |        |       |       |       |
|   3 |    TABLE ACCESS BY GLOBAL INDEX ROWID| mpos_aaa_his       |   197K|  7119K|       |     5   (0)| 00:00:01 |    18 |    18 |
|*  4 |     INDEX RANGE SCAN             | ID_POSXXXX_ZHSY       |     1 |       |       |     4   (0)| 00:00:01 |       |       |
|   5 |    NESTED LOOPS              |                   |     1 |    21 |       | 16710   (1)| 00:03:21 |       |       |
|*  6 |     TABLE ACCESS FULL             | aas_agent_ccc_info |     1 |    11 |       | 16704   (1)| 00:03:21 |       |       |
|   7 |     INLIST ITERATOR             |                   |       |       |       |        |       |       |       |
|*  8 |      INDEX RANGE SCAN             | IDX1_XXXX_AGENT_INFO       |     1 |    10 |       |     7   (0)| 00:00:01 |       |       |
--------------------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

   2 - filter( IS NULL)
   4 - access("T"."ORG_ID"=195116 AND "T"."ROUTE_FLAG"='1' AND "T"."POS_CND"='XXX' AND "T"."TRADE_STATUS"='00' AND
          "T"."TRADE_DATE">=TIMESTAMP' 2021-08-01 00:00:00.000000000' AND "T"."TRADE_DATE"<TIMESTAMP' 2021-09-01 00:00:00.000000000')
   6 - filter(LNNVL("AI"."SHOP_ID"<>:B1))
   8 - access((("A"."TOP_ORG_ID"=49694 OR "A"."TOP_ORG_ID"=52359 OR "A"."TOP_ORG_ID"=53858 OR "A"."TOP_ORG_ID"=56983 OR
          "A"."TOP_ORG_ID"=56986 OR "A"."TOP_ORG_ID"=57067 OR "A"."TOP_ORG_ID"=57290)) AND "AI"."ORG_ID"="A"."ORG_ID")

sql如下:


select 
   count(*) 交易笔数,to_char(t.trade_date ,'yyyy-mm-dd') as 交易日期,sum(t.trade_amount) 交易金额
    from   mpos_aaa_his t where 1=1
   and t.trade_status = '00'
   and t.org_id in 195116
   and t.POS_CND = 'XXXX'
   and t.route_flag = '1'
   and t.shop_id not  in
   (
       select ai.shop_id from aas_agent_ccc_info ai, aas_bbb_info a where ai.org_id = a.org_id and a.top_org_id in 
       (
              49694,
              52359,
              53858,
              56983,
              57067,
              56986,
              57290
       )
   )
   and (t.trade_date >= to_timestamp('2021-08-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss') and t.trade_date < to_timestamp('2021-09-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss'))
  group by  to_char(t.trade_date ,'yyyy-mm-dd');

你这个问题我认为不是出在group by上。问题大概也有两点
1.大数据量group by走了嵌套循环我认为不太不合适
2.看上去你使用了分区表,并且使用了全局索引,这不太合适,试试看能不能改成本地索引

针对以上两点,我建议你做以下修改。and t.shop_id not in 后面的sql提取出来形成一个内联视图,然后把这个内联视图和mpos_aaa_his进行关联之后做left join或right join 替代not in 记得加提示/+ use_hash(内联视图的名称或别名 t) no_merge(内联视图名)/
想了解更多的数据库知识可以关注我的公众号:唯一的小彬哥
大致的代码就像下面这样,你自己按上面思路调整一下。

select /*+ use_hash(t b) no_merge(b)*/    --前面/*+ use_hash(t b) no_merge(b)*/是提示,不是注释,不能去掉
   count(*) 交易笔数,to_char(t.trade_date ,'yyyy-mm-dd') as 交易日期,sum(t.trade_amount) 交易金额
    from   mpos_aaa_his t left join (
       select  distinct ai.shop_id from aas_agent_ccc_info ai, aas_bbb_info a where ai.org_id = a.org_id and a.top_org_id in 
       (
              49694,
              52359,
              53858,
              56983,
              57067,
              56986,
              57290
       )
   ) b on and t.shop_id = b.shop_id
   
     where 1=1
  
   and t.trade_status = '00'
   and t.org_id in 195116
   and t.POS_CND = 'XXXX'
   and t.route_flag = '1'
   and b.shop_id is null--这里新加的
   
   and (t.trade_date >= to_timestamp('2021-08-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss') and t.trade_date < to_timestamp('2021-09-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss'))
  group by  to_char(t.trade_date ,'yyyy-mm-dd');

不知道 行不行,可以执行以下 看看

如果不使用sql中的not in语句进行排序group,大约30左右

select ai.shop_id from aas_agent_ccc_info ai
至少这里可以去重
select distinct ai.shop_id from aas_agent_ccc_info ai

单纯group 那里,没啥可弄得。