楼主: 暗纹河豚毒

[SQL] 分组求max,min速度很快,但是求max-min速度很慢

[复制链接]
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
21#
发表于 2013-9-9 15:26 | 只看该作者
〇〇 发表于 2013-9-9 12:04
那就把中间结果连接来求

这种还是比较快的,虽然扫描了2次

select x.b,x.x-y.y from (
select b.b,
       max(b.id)x, /*或,*/
       min(b.id)y
  from big b,
       (select distinct e.a
          from e
        where e.a like '1%') m
where b.a>=3
   and b.a<=4
   and b.b= m.a
group by b.b)x,
(
select b.b,
       max(b.id)x, /*或,*/
       min(b.id)y
  from big b,
       (select distinct e.a
          from e
        where e.a like '1%') m
where b.a>=3
   and b.a<=4
   and b.b= m.a
group by b.b)y
where y.b=x.b;
执行计划
----------------------------------------------------------
Plan hash value: 3195090795

-------------------------------------------------------------------------------------
| Id  | Operation               | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |           |    13 |   676 |  1288   (4)| 00:00:01 |
|*  1 |  HASH JOIN              |           |    13 |   676 |  1288   (4)| 00:00:01 |
|   2 |   VIEW                  |           |    13 |   338 |   644   (4)| 00:00:01 |
|   3 |    HASH GROUP BY        |           |    13 |   182 |   644   (4)| 00:00:01 |
|*  4 |     HASH JOIN           |           |   128K|  1763K|   638   (3)| 00:00:01 |
|   5 |      VIEW               | VW_GBF_12 |    13 |    39 |     8  (13)| 00:00:01 |
|   6 |       HASH GROUP BY     |           |    13 |    39 |     8  (13)| 00:00:01 |
|*  7 |        TABLE ACCESS FULL| E         |   500 |  1500 |     7   (0)| 00:00:01 |
|*  8 |      TABLE ACCESS FULL  | BIG       |   280K|  3012K|   628   (3)| 00:00:01 |
|   9 |   VIEW                  |           |    13 |   338 |   644   (4)| 00:00:01 |
|  10 |    HASH GROUP BY        |           |    13 |   182 |   644   (4)| 00:00:01 |
|* 11 |     HASH JOIN           |           |   128K|  1763K|   638   (3)| 00:00:01 |
|  12 |      VIEW               | VW_GBF_6  |    13 |    39 |     8  (13)| 00:00:01 |
|  13 |       HASH GROUP BY     |           |    13 |    39 |     8  (13)| 00:00:01 |
|* 14 |        TABLE ACCESS FULL| E         |   500 |  1500 |     7   (0)| 00:00:01 |
|* 15 |      TABLE ACCESS FULL  | BIG       |   280K|  3012K|   628   (3)| 00:00:01 |
-------------------------------------------------------------------------------------

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

   1 - access("Y"."B"="X"."B")
   4 - access("B"."B"="ITEM_1")
   7 - filter(TO_CHAR("E"."A") LIKE '1%')
   8 - filter("B"."A">=3 AND "B"."A"<=4)
  11 - access("B"."B"="ITEM_1")
  14 - filter(TO_CHAR("E"."A") LIKE '1%')
  15 - filter("B"."A">=3 AND "B"."A"<=4)


统计信息
----------------------------------------------------------
          1  recursive calls
          0  db block gets
       4460  consistent gets
          0  physical reads
          0  redo size
        679  bytes sent via SQL*Net to client
        520  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          4  rows processed

使用道具 举报

回复
论坛徽章:
0
22#
 楼主| 发表于 2013-9-9 15:29 | 只看该作者
〇〇 发表于 2013-9-9 15:26
这种还是比较快的,虽然扫描了2次

select x.b,x.x-y.y from (

好的,我改写一下试试

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
23#
发表于 2013-9-9 15:30 | 只看该作者
〇〇 发表于 2013-9-9 15:26
这种还是比较快的,虽然扫描了2次

select x.b,x.x-y.y from (

改用with反而慢多了

with x as(
select b.b,
       max(b.id)x, /*或,*/
       min(b.id)y
  from big b,
       (select distinct e.a
          from e
        where e.a like '1%') m
where b.a>=3
   and b.a<=4
   and b.b= m.a
group by b.b)
select x.b,x.x-y.y from x,
x y
where y.b=x.b;
执行计划
----------------------------------------------------------
Plan hash value: 990172467

----------------------------------------------------------------------------------------------------------
| Id  | Operation                  | Name                        | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT           |                             |     2 |   104 |   906  (32)| 00:00:01 |
|   1 |  TEMP TABLE TRANSFORMATION |                             |       |       |            |          |
|   2 |   LOAD AS SELECT           | SYS_TEMP_0FD9D70E7_42BAC073 |       |       |            |          |
|   3 |    HASH GROUP BY           |                             |    13 |   182 |   901  (32)| 00:00:01 |
|*  4 |     HASH JOIN              |                             |  4961K|    66M|   659   (6)| 00:00:01 |
|*  5 |      TABLE ACCESS FULL     | E                           |   500 |  1500 |     7   (0)| 00:00:01 |
|*  6 |      TABLE ACCESS FULL     | BIG                         |   280K|  3012K|   628   (3)| 00:00:01 |
|*  7 |   HASH JOIN                |                             |     2 |   104 |     5  (20)| 00:00:01 |
|   8 |    VIEW                    |                             |    13 |   338 |     2   (0)| 00:00:01 |
|   9 |     TABLE ACCESS FULL      | SYS_TEMP_0FD9D70E7_42BAC073 |    13 |   182 |     2   (0)| 00:00:01 |
|  10 |    VIEW                    |                             |    13 |   338 |     2   (0)| 00:00:01 |
|  11 |     TABLE ACCESS FULL      | SYS_TEMP_0FD9D70E7_42BAC073 |    13 |   182 |     2   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------------

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

   4 - access("B"."B"="E"."A")
   5 - filter(TO_CHAR("E"."A") LIKE '1%')
   6 - filter("B"."A">=3 AND "B"."A"<=4)
   7 - access("Y"."B"="X"."B")


统计信息
----------------------------------------------------------
         55  recursive calls
          8  db block gets
       2272  consistent gets
          1  physical reads
        852  redo size
        679  bytes sent via SQL*Net to client
        520  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          4  rows processed

使用道具 举报

回复
论坛徽章:
30
生肖徽章:猴
日期:2015-03-20 10:13:49ITPUB 11周年纪念徽章
日期:2012-10-23 16:55:31优秀写手
日期:2015-03-07 06:00:14沸羊羊
日期:2015-03-13 13:26:07美羊羊
日期:2015-04-06 20:32:13天蝎座
日期:2015-07-20 12:34:47射手座
日期:2015-09-18 12:38:55乌索普
日期:2016-08-03 07:04:28奥运会纪念徽章:手球
日期:2016-09-26 07:19:26山治
日期:2016-10-19 05:48:10
24#
发表于 2013-9-9 15:31 | 只看该作者
暗纹河豚毒 发表于 2013-9-9 15:20
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------- ...

好难交流。

1)Note
-----
   - cardinality feedback used for this statement
   - Warning: basic plan statistics not available. These are only collected when:
       * hint 'gather_plan_statistics' is used for the statement or
       * parameter 'statistics_level' is set to 'ALL', at session or system level
至少最后一条没有设置收集级别为ALL。
2)第一次ELEC_METER_INFO表的实际记录为34条,而第二次则是2782条!建议收集相关表的统计信息。

使用道具 举报

回复
论坛徽章:
126
ITPUB元老
日期:2007-07-04 17:27:50会员2007贡献徽章
日期:2007-09-26 18:42:10现任管理团队成员
日期:2011-05-07 01:45:08优秀写手
日期:2015-01-09 06:00:14版主7段
日期:2015-07-16 02:10:00
25#
发表于 2013-9-9 15:32 来自手机 | 只看该作者
lz, 你目前第二个代码效率低是由于对大表的访问使用了index skip scan, 导致产生了很大的一致读, 我前面给的语句你测试一下, 按要求提供详细信息!

使用道具 举报

回复
论坛徽章:
0
26#
 楼主| 发表于 2013-9-9 15:36 | 只看该作者
阿吉2009 发表于 2013-9-9 15:31
好难交流。

1)Note

呵呵抱歉,LZ是新手

刚刚看到版主执行了DBMS_STATS.GATHER_TABLE_STATS,我再试一下

使用道具 举报

回复
论坛徽章:
30
生肖徽章:猴
日期:2015-03-20 10:13:49ITPUB 11周年纪念徽章
日期:2012-10-23 16:55:31优秀写手
日期:2015-03-07 06:00:14沸羊羊
日期:2015-03-13 13:26:07美羊羊
日期:2015-04-06 20:32:13天蝎座
日期:2015-07-20 12:34:47射手座
日期:2015-09-18 12:38:55乌索普
日期:2016-08-03 07:04:28奥运会纪念徽章:手球
日期:2016-09-26 07:19:26山治
日期:2016-10-19 05:48:10
27#
发表于 2013-9-9 15:40 | 只看该作者
本帖最后由 阿吉2009 于 2013-9-9 15:41 编辑
暗纹河豚毒 发表于 2013-9-9 15:36
呵呵抱歉,LZ是新手

刚刚看到版主执行了DBMS_STATS.GATHER_TABLE_STATS,我再试一下


如是表很大,可能要些时间,建议DB空闲时再做,且最好用100%的估算率,最好是也加上直方图。

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
28#
发表于 2013-9-9 15:41 | 只看该作者
bell6248 发表于 2013-9-9 15:32
lz, 你目前第二个代码效率低是由于对大表的访问使用了index skip scan, 导致产生了很大的一致读, 我前面给 ...

我的表没有索引,都是全表扫描,慢的全是cpu高

使用道具 举报

回复
论坛徽章:
0
29#
 楼主| 发表于 2013-9-9 15:51 | 只看该作者
本帖最后由 暗纹河豚毒 于 2013-9-9 16:27 编辑
bell6248 发表于 2013-9-9 15:32
lz, 你目前第二个代码效率低是由于对大表的访问使用了index skip scan, 导致产生了很大的一致读, 我前面给 ...

看到回复之前,已经执行过DBMS_STATS.GATHER_TABLE_STATS了。


下面是详细信息
15:42:14 ecms0219@ECMS> set autotrace on
15:42:22 ecms0219@ECMS> select /*+ no_merge(m) */ b.elec_meter_id elec_meter_id
15:43:18   2         max(b.total_used) - min(b.total_used) x
15:43:18   3    from BIGDATA b,
15:43:18   4         (select distinct e.meter_id
15:43:18   5            from ELEC_METER_INFO e,
15:43:18   6                 (select u.org_id
15:43:18   7                    from ORG_INFO u
15:43:18   8                   where u.super_org_id = '52ac306a38755fcf01388e69
95c007e') org
15:43:18   9           where e.is_delete = 'N'
15:43:18  10             and e.is_disable = 'N'
15:43:18  11             and e.is_init > 0
15:43:18  12             and e.org_stat_area = 0
15:43:18  13             and e.org_id = org.org_id) m
15:43:18  14   where b.treate_date >= '2013-01-01 00:00:00'
15:43:18  15     and b.treate_date <= '2014-01-01 00:00:00'
15:43:18  16     and b.elec_meter_id = m.meter_id
15:43:18  17   group by b.elec_meter_id
15:43:18  18   order by 1;

ELEC_METER_ID                                                             X
---------------------------------------------------------------- ----------
52ac306a38755fcf01388f0e2fbe0132                                      180.2
...
已选择37行。
已用时间:  00: 00: 00.13
执行计划
----------------------------------------------------------
Plan hash value: 1145997452
-------------------------------------------------------------------------------------------------------
| Id  | Operation                     | Name                  | Rows  | Bytes |Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |                       |   823 | 74070 |  813   (1)| 00:00:10 |
|   1 |  SORT GROUP BY                |                       |   823 | 74070 |  813   (1)| 00:00:10 |
|   2 |   NESTED LOOPS                |                       |       |       |           |          |
|   3 |    NESTED LOOPS               |                       |   823 | 74070 |  813   (1)| 00:00:10 |
|   4 |     VIEW                      |                       |     1 |    33 |   93   (3)| 00:00:02 |
|   5 |      HASH UNIQUE              |                       |     1 |   135 |   93   (3)| 00:00:02 |
|*  6 |       HASH JOIN               |                       |     1 |   135 |   92   (2)| 00:00:02 |
|*  7 |        TABLE ACCESS FULL      | US_ELECMETER_INFO     |    34 |  2346 |   69   (0)| 00:00:01 |
|*  8 |        TABLE ACCESS FULL      | US_ORGAN_INFOR        |    55 |  3630 |   22   (0)| 00:00:01 |
|*  9 |     INDEX RANGE SCAN          | UIDX_BS_TRE_ELEC_DATE |   823 |       |   10   (0)| 00:00:01 |
|  10 |    TABLE ACCESS BY INDEX ROWID| BS_TREATEDDATA        |   823 | 46911 |  720   (0)| 00:00:09 |
-------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   6 - access("E"."ORG_ID"="U"."ORG_ID")
   7 - filter("E"."ORG_ID" IS NOT NULL AND "E"."ORG_STAT_AREA"=0 AND
              TO_NUMBER("E"."IS_INIT")>0 AND "E"."IS_DISABLE"='N' AND "E"."IS_DELETE"='N')
   8 - filter("U"."SUPER_ORG_ID"='52ac306a38755fcf01388e69195c007e')
   9 - access("B"."ELEC_METER_ID"="M"."METER_ID" AND "B"."TREATE_DATE">='2013-01-01 00:00:00'
              AND "B"."TREATE_DATE"<='2014-01-01 00:00:00')
       filter("B"."ELEC_METER_ID" IS NOT NULL)

统计信息
----------------------------------------------------------
          1  recursive calls
          0  db block gets
      33746  consistent gets
          0  physical reads
          0  redo size
       2082  bytes sent via SQL*Net to client
        385  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
         37  rows processed

15:43:35 ecms0219@ECMS>

使用道具 举报

回复
论坛徽章:
126
ITPUB元老
日期:2007-07-04 17:27:50会员2007贡献徽章
日期:2007-09-26 18:42:10现任管理团队成员
日期:2011-05-07 01:45:08优秀写手
日期:2015-01-09 06:00:14版主7段
日期:2015-07-16 02:10:00
30#
发表于 2013-9-9 16:01 来自手机 | 只看该作者
暗纹河豚毒 发表于 2013-9-9 15:51
看到回复之前,已经执行过DBMS_STATS.GATHER_TABLE_STATS了。



逻辑读目前的数目大大下降了, 改过语句的执行计划正常了.

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表