如何提高GROUP BY分组查询效率

uging 2013-09-03 09:21:29
最近工作中遇到一个性能问题,自己搞了好久还是没搞定,拿到论坛上来,希望各位大虾给点意见。
查询的SQL如下:
SELECT A,B,C,D,COUNT(1) FROM T WHERE C=@C AND D IN (@D) GROUP BY A,B
因为数据量比较大,所以这条SQL效率就变得特别慢,而且这个是用在页面查询上的,分页后每次查询都要花到8到9秒钟,页面卡死在那边,希望高手们帮小弟解答,小弟这边先谢过了。
...全文
12900 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
uging 2013-09-04
  • 打赏
  • 举报
回复
引用 15 楼 rainbowsix 的回复:
[quote=引用 13 楼 uging 的回复:] [quote=引用 11 楼 rainbowsix 的回复:] [quote=引用 10 楼 uging 的回复:] [quote=引用 6 楼 uging 的回复:] [quote=引用 3 楼 lrbyantai 的回复:] 针对此SQL语句,可在C、D字段建索引,A、B建组合索引
这个我已经试过了,加索引效果甚微,查询效果还是一样的慢。[/quote] 贴上SQL
SELECT
  DEALER_ID,
  DEALER_BUSCODE,
  DEALER_NAME,
  DEALER_STATUS,
  OFFER_ID,
  OFFER_NAME,
  CHANNEL_ID,
  SUB_CHANNEL_ID,
  DISTY_ID,
  DISTY_BUSCODE,
  DISTY_NAME,
  REGION_CODE,
  REGION_NAME,
  O_ACTIVATION_TIME,
  P_ACTIVATION_TIME,
  ACTIVATION_DATE,
  STATE_CODE,
  STATE_NAME,
  PACKAGE_ID,
  PACKAGE_NAME,
  SALES_PIC,
  MSISDN,
  COUNT(1)
FROM UM2_ACTI_DTL_201305
WHERE OFFER_TYPE IN(1,3)
    AND ACTIVATION_TYPE = 3
    AND OFFER_ID IN(20000001,20000031,20010010)
    AND PACKAGE_ID IN(322,197,326,566,318,576,277,374,377,581)
    AND CHANNEL_ID IN(1,2,4)
    GROUP BY DEALER_ID,PACKAGE_ID,ACTIVATION_DATE
[/quote] OFFER_ID CHANNEL_ID 有建索引的话 试下这样: 像这样 内容不多的in你用 = 试试看,如果不行我也没办法了额,不了解业务,也不知道应用场景,不好说。 另: 你这查询返回多少数据?[/quote] in语句的地方用=我也试过,没什么效果。 该查询返回的数据在17w左右[/quote] 17W 的话,慢是正常的,不慢反而不正常了哦~~ [/quote] 谢谢,晚上我自己搞了一下,结果出来了
SELECT  DEALER_ID,  DEALER_BUSCODE,  DEALER_NAME,  DEALER_STATUS,  OFFER_ID,  OFFER_NAME,  CHANNEL_ID,  SUB_CHANNEL_ID,  DISTY_ID,  DISTY_BUSCODE,  DISTY_NAME,  REGION_CODE,  REGION_NAME,  O_ACTIVATION_TIME,  P_ACTIVATION_TIME,  ACTIVATION_DATE,  STATE_CODE,  STATE_NAME,  PACKAGE_ID,  PACKAGE_NAME,  SALES_PIC,  MSISDN,  COUNT(distinct DEALER_ID,PACKAGE_ID,ACTIVATION_DATE),count(*) FROM UM2_ACTI_DTL_201305WHERE OFFER_TYPE IN(1,3)    AND ACTIVATION_TYPE = 3    AND OFFER_ID IN(20000001,20000031,20010010)    AND PACKAGE_ID IN(322,197,326,566,318,576,277,374,377,581)    AND CHANNEL_ID IN(1,2,4)    GROUP BY DEALER_ID,PACKAGE_ID,ACTIVATION_DATE
这样效率就高了很多
蛋黄车 2013-09-04
  • 打赏
  • 举报
回复
针对此SQL语句,可在C、D字段建索引,A、B建组合索引
  • 打赏
  • 举报
回复
你确定你这条语句能执行???不在聚集函数中的列,全部要出现在group by语句中,你现在的group by 中少了C,D两列,报错了吧
uging 2013-09-04
  • 打赏
  • 举报
回复
自己先抢个沙发
无聊找乐 2013-09-04
  • 打赏
  • 举报
回复
引用 13 楼 uging 的回复:
[quote=引用 11 楼 rainbowsix 的回复:] [quote=引用 10 楼 uging 的回复:] [quote=引用 6 楼 uging 的回复:] [quote=引用 3 楼 lrbyantai 的回复:] 针对此SQL语句,可在C、D字段建索引,A、B建组合索引
这个我已经试过了,加索引效果甚微,查询效果还是一样的慢。[/quote] 贴上SQL
SELECT
  DEALER_ID,
  DEALER_BUSCODE,
  DEALER_NAME,
  DEALER_STATUS,
  OFFER_ID,
  OFFER_NAME,
  CHANNEL_ID,
  SUB_CHANNEL_ID,
  DISTY_ID,
  DISTY_BUSCODE,
  DISTY_NAME,
  REGION_CODE,
  REGION_NAME,
  O_ACTIVATION_TIME,
  P_ACTIVATION_TIME,
  ACTIVATION_DATE,
  STATE_CODE,
  STATE_NAME,
  PACKAGE_ID,
  PACKAGE_NAME,
  SALES_PIC,
  MSISDN,
  COUNT(1)
FROM UM2_ACTI_DTL_201305
WHERE OFFER_TYPE IN(1,3)
    AND ACTIVATION_TYPE = 3
    AND OFFER_ID IN(20000001,20000031,20010010)
    AND PACKAGE_ID IN(322,197,326,566,318,576,277,374,377,581)
    AND CHANNEL_ID IN(1,2,4)
    GROUP BY DEALER_ID,PACKAGE_ID,ACTIVATION_DATE
[/quote] OFFER_ID CHANNEL_ID 有建索引的话 试下这样: 像这样 内容不多的in你用 = 试试看,如果不行我也没办法了额,不了解业务,也不知道应用场景,不好说。 另: 你这查询返回多少数据?[/quote] in语句的地方用=我也试过,没什么效果。 该查询返回的数据在17w左右[/quote] 17W 的话,慢是正常的,不慢反而不正常了哦~~
uging 2013-09-04
  • 打赏
  • 举报
回复
引用 12 楼 bayougeng 的回复:
你group by这么多字段……要我是数据库我也想不出来怎么能让你快
这个没办法啊,客户需要这么分组
uging 2013-09-04
  • 打赏
  • 举报
回复
引用 11 楼 rainbowsix 的回复:
[quote=引用 10 楼 uging 的回复:] [quote=引用 6 楼 uging 的回复:] [quote=引用 3 楼 lrbyantai 的回复:] 针对此SQL语句,可在C、D字段建索引,A、B建组合索引
这个我已经试过了,加索引效果甚微,查询效果还是一样的慢。[/quote] 贴上SQL
SELECT
  DEALER_ID,
  DEALER_BUSCODE,
  DEALER_NAME,
  DEALER_STATUS,
  OFFER_ID,
  OFFER_NAME,
  CHANNEL_ID,
  SUB_CHANNEL_ID,
  DISTY_ID,
  DISTY_BUSCODE,
  DISTY_NAME,
  REGION_CODE,
  REGION_NAME,
  O_ACTIVATION_TIME,
  P_ACTIVATION_TIME,
  ACTIVATION_DATE,
  STATE_CODE,
  STATE_NAME,
  PACKAGE_ID,
  PACKAGE_NAME,
  SALES_PIC,
  MSISDN,
  COUNT(1)
FROM UM2_ACTI_DTL_201305
WHERE OFFER_TYPE IN(1,3)
    AND ACTIVATION_TYPE = 3
    AND OFFER_ID IN(20000001,20000031,20010010)
    AND PACKAGE_ID IN(322,197,326,566,318,576,277,374,377,581)
    AND CHANNEL_ID IN(1,2,4)
    GROUP BY DEALER_ID,PACKAGE_ID,ACTIVATION_DATE
[/quote] OFFER_ID CHANNEL_ID 有建索引的话 试下这样: 像这样 内容不多的in你用 = 试试看,如果不行我也没办法了额,不了解业务,也不知道应用场景,不好说。 另: 你这查询返回多少数据?[/quote] in语句的地方用=我也试过,没什么效果。 该查询返回的数据在17w左右
bayougeng 2013-09-04
  • 打赏
  • 举报
回复
你group by这么多字段……要我是数据库我也想不出来怎么能让你快
无聊找乐 2013-09-04
  • 打赏
  • 举报
回复
引用 10 楼 uging 的回复:
[quote=引用 6 楼 uging 的回复:] [quote=引用 3 楼 lrbyantai 的回复:] 针对此SQL语句,可在C、D字段建索引,A、B建组合索引
这个我已经试过了,加索引效果甚微,查询效果还是一样的慢。[/quote] 贴上SQL
SELECT
  DEALER_ID,
  DEALER_BUSCODE,
  DEALER_NAME,
  DEALER_STATUS,
  OFFER_ID,
  OFFER_NAME,
  CHANNEL_ID,
  SUB_CHANNEL_ID,
  DISTY_ID,
  DISTY_BUSCODE,
  DISTY_NAME,
  REGION_CODE,
  REGION_NAME,
  O_ACTIVATION_TIME,
  P_ACTIVATION_TIME,
  ACTIVATION_DATE,
  STATE_CODE,
  STATE_NAME,
  PACKAGE_ID,
  PACKAGE_NAME,
  SALES_PIC,
  MSISDN,
  COUNT(1)
FROM UM2_ACTI_DTL_201305
WHERE OFFER_TYPE IN(1,3)
    AND ACTIVATION_TYPE = 3
    AND OFFER_ID IN(20000001,20000031,20010010)
    AND PACKAGE_ID IN(322,197,326,566,318,576,277,374,377,581)
    AND CHANNEL_ID IN(1,2,4)
    GROUP BY DEALER_ID,PACKAGE_ID,ACTIVATION_DATE
[/quote] OFFER_ID CHANNEL_ID 有建索引的话 试下这样: 像这样 内容不多的in你用 = 试试看,如果不行我也没办法了额,不了解业务,也不知道应用场景,不好说。 另: 你这查询返回多少数据?
uging 2013-09-04
  • 打赏
  • 举报
回复
引用 6 楼 uging 的回复:
[quote=引用 3 楼 lrbyantai 的回复:] 针对此SQL语句,可在C、D字段建索引,A、B建组合索引
这个我已经试过了,加索引效果甚微,查询效果还是一样的慢。[/quote] 贴上SQL
SELECT
  DEALER_ID,
  DEALER_BUSCODE,
  DEALER_NAME,
  DEALER_STATUS,
  OFFER_ID,
  OFFER_NAME,
  CHANNEL_ID,
  SUB_CHANNEL_ID,
  DISTY_ID,
  DISTY_BUSCODE,
  DISTY_NAME,
  REGION_CODE,
  REGION_NAME,
  O_ACTIVATION_TIME,
  P_ACTIVATION_TIME,
  ACTIVATION_DATE,
  STATE_CODE,
  STATE_NAME,
  PACKAGE_ID,
  PACKAGE_NAME,
  SALES_PIC,
  MSISDN,
  COUNT(1)
FROM UM2_ACTI_DTL_201305
WHERE OFFER_TYPE IN(1,3)
    AND ACTIVATION_TYPE = 3
    AND OFFER_ID IN(20000001,20000031,20010010)
    AND PACKAGE_ID IN(322,197,326,566,318,576,277,374,377,581)
    AND CHANNEL_ID IN(1,2,4)
    GROUP BY DEALER_ID,PACKAGE_ID,ACTIVATION_DATE
uging 2013-09-04
  • 打赏
  • 举报
回复
引用 8 楼 rainbowsix 的回复:
[quote=引用 7 楼 uging 的回复:] [quote=引用 4 楼 rainbowsix 的回复:] 建索引,然后尽可能的过滤掉不符合条件的数据,然后再分组
下面是实际用到的SQL,请帮我看一下,索引什么的已经加过了,没多大效果 SELECT DEALER_ID, DEALER_BUSCODE, DEALER_NAME, DEALER_STATUS, OFFER_ID, OFFER_NAME, CHANNEL_ID, SUB_CHANNEL_ID, DISTY_ID, DISTY_BUSCODE, DISTY_NAME, REGION_CODE, REGION_NAME, O_ACTIVATION_TIME, P_ACTIVATION_TIME, ACTIVATION_DATE, STATE_CODE, STATE_NAME, PACKAGE_ID, PACKAGE_NAME, SALES_PIC, MSISDN, COUNT(1) FROM UM2_ACTI_DTL_201305 WHERE OFFER_TYPE IN(1,3) AND ACTIVATION_TYPE = 3 AND OFFER_ID IN(20000001,20000031,20010010) AND PACKAGE_ID IN(322,197,326,566,318,576,277,374,377,581) AND CHANNEL_ID IN(1,2,4) GROUP BY DEALER_ID,PACKAGE_ID,ACTIVATION_DATE[/quote] 你这样的sql不能执行吧。 除了group by的列 ,其它选择的列必须要有统计函数的吧,类似于sum,average之类的[/quote] 可以执行的,效率比较差
无聊找乐 2013-09-04
  • 打赏
  • 举报
回复
引用 7 楼 uging 的回复:
[quote=引用 4 楼 rainbowsix 的回复:] 建索引,然后尽可能的过滤掉不符合条件的数据,然后再分组
下面是实际用到的SQL,请帮我看一下,索引什么的已经加过了,没多大效果 SELECT DEALER_ID, DEALER_BUSCODE, DEALER_NAME, DEALER_STATUS, OFFER_ID, OFFER_NAME, CHANNEL_ID, SUB_CHANNEL_ID, DISTY_ID, DISTY_BUSCODE, DISTY_NAME, REGION_CODE, REGION_NAME, O_ACTIVATION_TIME, P_ACTIVATION_TIME, ACTIVATION_DATE, STATE_CODE, STATE_NAME, PACKAGE_ID, PACKAGE_NAME, SALES_PIC, MSISDN, COUNT(1) FROM UM2_ACTI_DTL_201305 WHERE OFFER_TYPE IN(1,3) AND ACTIVATION_TYPE = 3 AND OFFER_ID IN(20000001,20000031,20010010) AND PACKAGE_ID IN(322,197,326,566,318,576,277,374,377,581) AND CHANNEL_ID IN(1,2,4) GROUP BY DEALER_ID,PACKAGE_ID,ACTIVATION_DATE[/quote] 你这样的sql不能执行吧。 除了group by的列 ,其它选择的列必须要有统计函数的吧,类似于sum,average之类的
uging 2013-09-04
  • 打赏
  • 举报
回复
引用 4 楼 rainbowsix 的回复:
建索引,然后尽可能的过滤掉不符合条件的数据,然后再分组
下面是实际用到的SQL,请帮我看一下,索引什么的已经加过了,没多大效果 SELECT DEALER_ID, DEALER_BUSCODE, DEALER_NAME, DEALER_STATUS, OFFER_ID, OFFER_NAME, CHANNEL_ID, SUB_CHANNEL_ID, DISTY_ID, DISTY_BUSCODE, DISTY_NAME, REGION_CODE, REGION_NAME, O_ACTIVATION_TIME, P_ACTIVATION_TIME, ACTIVATION_DATE, STATE_CODE, STATE_NAME, PACKAGE_ID, PACKAGE_NAME, SALES_PIC, MSISDN, COUNT(1) FROM UM2_ACTI_DTL_201305 WHERE OFFER_TYPE IN(1,3) AND ACTIVATION_TYPE = 3 AND OFFER_ID IN(20000001,20000031,20010010) AND PACKAGE_ID IN(322,197,326,566,318,576,277,374,377,581) AND CHANNEL_ID IN(1,2,4) GROUP BY DEALER_ID,PACKAGE_ID,ACTIVATION_DATE
uging 2013-09-04
  • 打赏
  • 举报
回复
引用 3 楼 lrbyantai 的回复:
针对此SQL语句,可在C、D字段建索引,A、B建组合索引
这个我已经试过了,加索引效果甚微,查询效果还是一样的慢。
uging 2013-09-04
  • 打赏
  • 举报
回复
引用 2 楼 xxhhbb1538 的回复:
你确定你这条语句能执行???不在聚集函数中的列,全部要出现在group by语句中,你现在的group by 中少了C,D两列,报错了吧
你说的对,我只是举个例子,实际的SQL比较复杂就没有贴出来。 但是假设SQL是正确的该怎么优化呢?实际的需求是按几个字段分组,然后统计出分组中每条记录的条数,该怎么实现?
无聊找乐 2013-09-04
  • 打赏
  • 举报
回复
建索引,然后尽可能的过滤掉不符合条件的数据,然后再分组

81,092

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧