楼主: myfriend2010

[FAQ] sql 使CPU使用100%,棘手!

[复制链接]
论坛徽章:
21
在线时间
日期:2007-07-25 04:01:022012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:23马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:142012新春纪念徽章
日期:2012-02-13 15:09:23
111#
发表于 2007-12-14 11:09 | 只看该作者
并且因为接下来你所要的数据都是在(GROUP_ID+PRE_M_ARPU_D)或是在GROUP_ID这个层次上的,所以,要使用V_HML_EAL_tem中的数据的话,就总会有个GROUP BY GROUP_ID,PRE_M_ARPU_D,或是GROUP BY GROUP_ID?

那样的话,LZ的版本跟我的版本的结果实在是没什么区别了,除了写法不同。

这个就是我在#99中提出的问题。从LZ多给的信息来看,实际上那个SQL能在GROUP_ID+PRE_M_ARPU_D上是唯一的话就应当是最好的了,虽然不是一定要-因为接下来还会做GROUP BY。

所以,我觉得我的版本应当在业务逻辑上是满足了LZ的要求?

使用道具 举报

回复
招聘 : Linux运维
论坛徽章:
235
紫蜘蛛
日期:2007-09-26 17:05:46玉兔
日期:2007-09-26 17:05:05现任管理团队成员
日期:2011-05-07 01:45:08玉兔
日期:2006-08-29 20:38:48紫蜘蛛
日期:2007-09-26 17:05:34阿斯顿马丁
日期:2013-11-19 10:38:16奔驰
日期:2013-10-16 09:08:58红旗
日期:2014-01-09 11:57:39路虎
日期:2013-08-13 14:52:35林肯
日期:2015-05-19 13:01:16
112#
 楼主| 发表于 2007-12-14 11:53 | 只看该作者
原帖由 askgyliu 于 2007-12-14 10:49 发表


嗯,看起来我们看问题的角度很不相同。

我的意思是说EXFMT1中的SQL跟EXFMT2中的SQL的区别不止是TEMP跟FACT那么简单。所以你在#63中的这句话“exfmt2.txt为10月份的表做的sql,但是把临时表session.V_PRE_EXP_GROUP_CUST1换成fact表,执行正常,也就是不会报CPU使用100%”是很难成立的。



你觉得很难成立对吧!这也就是我觉得棘手的地方!不知道为什么DB2会这样!迷惑的很

使用道具 举报

回复
招聘 : Linux运维
论坛徽章:
235
紫蜘蛛
日期:2007-09-26 17:05:46玉兔
日期:2007-09-26 17:05:05现任管理团队成员
日期:2011-05-07 01:45:08玉兔
日期:2006-08-29 20:38:48紫蜘蛛
日期:2007-09-26 17:05:34阿斯顿马丁
日期:2013-11-19 10:38:16奔驰
日期:2013-10-16 09:08:58红旗
日期:2014-01-09 11:57:39路虎
日期:2013-08-13 14:52:35林肯
日期:2015-05-19 13:01:16
113#
 楼主| 发表于 2007-12-14 12:01 | 只看该作者
原帖由 askgyliu 于 2007-12-14 10:57 发表


我的版本就是刚好包括了这三种情况:

1) 离网客户:aa.LEAVE_DATE <= '3000-11-30 00:00:00'
2) 新入网客户: aa.on_net_time=4
3) inner join V_HML_EAL_TEM就表示存在:
  left outer join V_PRE_EXP_GROUP_CUST1 a
    on aa.cust_id = a.cust_id
跟 where a.cust_id is not null

这里只是一个小技巧:
  select <something>
  from table_a left outer join table_b on <some conditions>
  where table_b.<a-non-null-field> is not null

  select <something>
  from table_a inner join table_b on <some conditions>
出来的结果是一样的。

这种写法平常不太会用到。但在LZ的这种情况下,恰好可以派上用场。  



我承认有这么一写法!但是要保证外关联只能取到1条记录!不然就会有误!

好比:a表
id  name
1  b
2  c
3  d
b 表
id acount
1  1000
1  2000
3  100
LZ可以执行select a.id,a.name,b.id,b.acount from a left outer join b on a.id = b.id看看会得到什么!?

使用道具 举报

回复
论坛徽章:
21
在线时间
日期:2007-07-25 04:01:022012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:23马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:142012新春纪念徽章
日期:2012-02-13 15:09:23
114#
发表于 2007-12-14 12:42 | 只看该作者
原帖由 myfriend2010 于 2007-12-14 12:01 发表



我承认有这么一写法!但是要保证外关联只能取到1条记录!不然就会有误!

好比:a表
id  name
1  b
2  c
3  d
b 表
id acount
1  1000
1  2000
3  100
LZ可以执行select a.id,a.name,b.id,b.acount from a left outer join b on a.id = b.id看看会得到什么!?


You still don't get what I mean.

1) select a.id,a.name,b.id,b.acount from a left outer join b on a.id = b.id

2) select a.id,a.name,b.id,b.acount from a left outer join b on a.id = b.id where b.id is not null

3) select a.id,a.name,b.id,b.acount from a inner join b on a.id = b.id

Statement 1 is totally different from statement 2 & 3. However, statement 2 & 3 will produce identical result. This is the trick I used in my version.

使用道具 举报

回复
论坛徽章:
21
在线时间
日期:2007-07-25 04:01:022012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:23马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:142012新春纪念徽章
日期:2012-02-13 15:09:23
115#
发表于 2007-12-14 12:44 | 只看该作者
原帖由 askgyliu 于 2007-12-14 12:42 发表


You still don't get what I mean.

1) select a.id,a.name,b.id,b.acount from a left outer join b on a.id = b.id

2) select a.id,a.name,b.id,b.acount from a left outer join b on a.id = b.id where b.id is not null

3) select a.id,a.name,b.id,b.acount from a inner join b on a.id = b.id

Statement 1 is totally different from statement 2 & 3. However, statement 2 & 3 will produce identical result. This is the trick I used in my version.


You are using statement 3 in the original query, and I am using statement 2 in my query, so that I can integrate all the conditions into a single simple select statement.

使用道具 举报

回复
论坛徽章:
21
在线时间
日期:2007-07-25 04:01:022012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:23马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:142012新春纪念徽章
日期:2012-02-13 15:09:23
116#
发表于 2007-12-14 12:52 | 只看该作者
原帖由 myfriend2010 于 2007-12-14 11:53 发表



你觉得很难成立对吧!这也就是我觉得棘手的地方!不知道为什么DB2会这样!迷惑的很


This is nothing to do with DB2, Oracle, or what so ever.

Part1 from exfmt2:
     select b.cust_group_id as group_id, aa.pre_m_arpu_d,sum(aa.PRE_M_ARPU)
              as arpu,sum(cc.m) as m,sum(cc.CLV) as clv, count(b.cust_id) as
              EXIST_CUST_C, sum(aa.NOW_ARPU) as EXIST_SUM_NOW_ARPU
      from
         (select distinct cust_id
         from ccp.PAR_CUST_CUST_GRP_ASSOC_200709 ) a inner join
              ccp.PAR_CUST_CUST_GRP_ASSOC_200710 b on b.cust_id = a.cust_id
              inner join ccp.CUST_CHURN_INFO_200710 aa on
              aa.cust_id=a.cust_id inner join ccp.CUST_CCP_INFO_200710 cc on
              cc.cust_id=a.cust_id
      group by b.cust_group_id,aa.pre_m_arpu_d

Part 1 from exfmt1:
      select b.cust_group_id as group_id, aa.pre_m_arpu_d,sum(aa.PRE_M_ARPU)
              as arpu,sum(cc.m) as m,sum(cc.CLV) as clv, count(b.cust_id) as
              EXIST_CUST_C, sum(aa.NOW_ARPU) as EXIST_SUM_NOW_ARPU
      from session.V_PRE_EXP_GROUP_CUST1 a inner join
              ccp.PAR_CUST_CUST_GRP_ASSOC_200710 b on b.cust_id = a.cust_id
              inner join ccp.CUST_CHURN_INFO_200710 aa on
              aa.cust_id=a.cust_id inner join ccp.CUST_CCP_INFO_200710 cc on
              cc.cust_id=a.cust_id
      group by b.cust_group_id,aa.pre_m_arpu_d

你觉得这两者的差别只是TEMP跟FACT吗?一个简单的地方,在Part1 from exfmt2中,DB2知道CUST_ID是唯一并且是排序的,而在Part 1 from exfmt1中,DB2能知道CUST_ID是唯一的吗?

使用道具 举报

回复
论坛徽章:
21
在线时间
日期:2007-07-25 04:01:022012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:23马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:142012新春纪念徽章
日期:2012-02-13 15:09:23
117#
发表于 2007-12-14 12:58 | 只看该作者
/home/db2inst/sql_performance/test2 > db2 -v "select * from a"
select * from a

ID          NAME
----------- ----------
          1 b
          2 c
          3 d

  3 record(s) selected.


/home/db2inst/sql_performance/test2 > db2 -v "select * from b"
select * from b

ID          ACCOUNT
----------- -----------
          1        1000
          1        2000
          3         100

  3 record(s) selected.

<这里是LZ的写法>
/home/db2inst/sql_performance/test2 > db2 -v "select a.id,a.name,b.id,b.account from a inner join b on a.id = b.id"
select a.id,a.name,b.id,b.account from a inner join b on a.id = b.id

ID          NAME       ID          ACCOUNT
----------- ---------- ----------- -----------
          1 b                    1        1000
          1 b                    1        2000
          3 d                    3         100

  3 record(s) selected.

<注意这里。这就是我讲的小技巧。我版本实际上用到的写法>
/home/db2inst/sql_performance/test2 >  on a.id = b.id where b.id is not null"                                      <
select a.id,a.name,b.id,b.account from a left outer join b on a.id = b.id where b.id is not null

ID          NAME       ID          ACCOUNT
----------- ---------- ----------- -----------
          1 b                    1        1000
          1 b                    1        2000
          3 d                    3         100

  3 record(s) selected.

<这里是大部分人都会知道的LEFT OUTER JOIN的写法,也是LZ认为我的版本用的而实际上不是。>
/home/db2inst/sql_performance/test2 > db2 -v "select a.id,a.name,b.id,b.account from a left outer join b on a.id = >
select a.id,a.name,b.id,b.account from a left outer join b on a.id = b.id

ID          NAME       ID          ACCOUNT
----------- ---------- ----------- -----------
          1 b                    1        1000
          1 b                    1        2000
          2 c                    -           -
          3 d                    3         100

  4 record(s) selected.

[ 本帖最后由 askgyliu 于 2007-12-14 13:04 编辑 ]

使用道具 举报

回复
招聘 : Linux运维
论坛徽章:
235
紫蜘蛛
日期:2007-09-26 17:05:46玉兔
日期:2007-09-26 17:05:05现任管理团队成员
日期:2011-05-07 01:45:08玉兔
日期:2006-08-29 20:38:48紫蜘蛛
日期:2007-09-26 17:05:34阿斯顿马丁
日期:2013-11-19 10:38:16奔驰
日期:2013-10-16 09:08:58红旗
日期:2014-01-09 11:57:39路虎
日期:2013-08-13 14:52:35林肯
日期:2015-05-19 13:01:16
118#
 楼主| 发表于 2007-12-14 13:02 | 只看该作者
原帖由 askgyliu 于 2007-12-14 12:52 发表


This is nothing to do with DB2, Oracle, or what so ever.

Part1 from exfmt2:
     select b.cust_group_id as group_id, aa.pre_m_arpu_d,sum(aa.PRE_M_ARPU)
              as arpu,sum(cc.m) as m,sum(cc.CLV) as clv, count(b.cust_id) as
              EXIST_CUST_C, sum(aa.NOW_ARPU) as EXIST_SUM_NOW_ARPU
      from
         (select distinct cust_id
         from ccp.PAR_CUST_CUST_GRP_ASSOC_200709 ) a inner join
              ccp.PAR_CUST_CUST_GRP_ASSOC_200710 b on b.cust_id = a.cust_id
              inner join ccp.CUST_CHURN_INFO_200710 aa on
              aa.cust_id=a.cust_id inner join ccp.CUST_CCP_INFO_200710 cc on
              cc.cust_id=a.cust_id
      group by b.cust_group_id,aa.pre_m_arpu_d

Part 1 from exfmt1:
      select b.cust_group_id as group_id, aa.pre_m_arpu_d,sum(aa.PRE_M_ARPU)
              as arpu,sum(cc.m) as m,sum(cc.CLV) as clv, count(b.cust_id) as
              EXIST_CUST_C, sum(aa.NOW_ARPU) as EXIST_SUM_NOW_ARPU
      from session.V_PRE_EXP_GROUP_CUST1 a inner join
              ccp.PAR_CUST_CUST_GRP_ASSOC_200710 b on b.cust_id = a.cust_id
              inner join ccp.CUST_CHURN_INFO_200710 aa on
              aa.cust_id=a.cust_id inner join ccp.CUST_CCP_INFO_200710 cc on
              cc.cust_id=a.cust_id
      group by b.cust_group_id,aa.pre_m_arpu_d

你觉得这两者的差别只是TEMP跟FACT吗?一个简单的地方,在Part1 from exfmt2中,DB2知道CUST_ID是唯一并且是排序的,而在Part 1 from exfmt1中,DB2能知道CUST_ID是唯一的吗?


对DB2内部是怎么执行的,我不清楚撒!你确定exfmt2是最佳选择吗?

使用道具 举报

回复
招聘 : Linux运维
论坛徽章:
235
紫蜘蛛
日期:2007-09-26 17:05:46玉兔
日期:2007-09-26 17:05:05现任管理团队成员
日期:2011-05-07 01:45:08玉兔
日期:2006-08-29 20:38:48紫蜘蛛
日期:2007-09-26 17:05:34阿斯顿马丁
日期:2013-11-19 10:38:16奔驰
日期:2013-10-16 09:08:58红旗
日期:2014-01-09 11:57:39路虎
日期:2013-08-13 14:52:35林肯
日期:2015-05-19 13:01:16
119#
 楼主| 发表于 2007-12-14 13:06 | 只看该作者
原帖由 askgyliu 于 2007-12-14 12:58 发表
/home/db2inst/sql_performance/test2 > db2 -v "select * from a"
select * from a

ID          NAME
----------- ----------
          1 b
          2 c
          3 d

  3 record(s) selected.


/home/db2inst/sql_performance/test2 > db2 -v "select * from b"
select * from b

ID          ACCOUNT
----------- -----------
          1        1000
          1        2000
          3         100

  3 record(s) selected.


/home/db2inst/sql_performance/test2 > db2 -v "select a.id,a.name,b.id,b.account from a inner join b on a.id = b.id"
select a.id,a.name,b.id,b.account from a inner join b on a.id = b.id

ID          NAME       ID          ACCOUNT
----------- ---------- ----------- -----------
          1 b                    1        1000
          1 b                    1        2000
          3 d                    3         100

  3 record(s) selected.


/home/db2inst/sql_performance/test2 >  on a.id = b.id where b.id is not null"                                      <
select a.id,a.name,b.id,b.account from a left outer join b on a.id = b.id where b.id is not null

ID          NAME       ID          ACCOUNT
----------- ---------- ----------- -----------
          1 b                    1        1000
          1 b                    1        2000
          3 d                    3         100

  3 record(s) selected.


/home/db2inst/sql_performance/test2 > db2 -v "select a.id,a.name,b.id,b.account from a left outer join b on a.id = >
select a.id,a.name,b.id,b.account from a left outer join b on a.id = b.id

ID          NAME       ID          ACCOUNT
----------- ---------- ----------- -----------
          1 b                    1        1000
          1 b                    1        2000
          2 c                    -           -
          3 d                    3         100

  4 record(s) selected.


我觉得你的做法,不应该是最佳的吧 !把inner join 刻意换成left outer join 不应该吧!

使用道具 举报

回复
论坛徽章:
21
在线时间
日期:2007-07-25 04:01:022012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:232012新春纪念徽章
日期:2012-02-13 15:09:23马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:142012新春纪念徽章
日期:2012-02-13 15:09:23
120#
发表于 2007-12-14 13:09 | 只看该作者
原帖由 myfriend2010 于 2007-12-14 13:02 发表


对DB2内部是怎么执行的,我不清楚撒!你确定exfmt2是最佳选择吗?


这两个SQL是完全不相同的,而不是“只是TEMP跟FACT的差别”。PERIOD

至于那个会比较好,得测试。

同样的两个SQL,不同的DATA PATTERN,不同的硬件设置,等等,可能PERFORMANCE完全相反。

PERFORMANCE应当是具体情况具体分析。

使用道具 举报

回复

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

本版积分规则 发表回复

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