免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1949 | 回复: 3
打印 上一主题 下一主题

奇怪。请帮忙分析一下为什么Rollup比简单SUM速度还快。 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-03-09 17:15 |只看该作者 |倒序浏览
是Try几个Oracle分析函数的时候发现使用rollup的语句比不使用的简单sum还要快些。搞不懂怎么回事,特别上来请教一下大家。

我用的是HPUX上架设的Oracle 8174
有一个比较大的Table,共170多万行记录。

使用如下语句RUN40次平均用时4.322525秒

  1. SELECT NVL(segment,'SUMMARY') AS segment,SUM(qty) FROM
  2. tablename
  3. GROUP BY ROLLUP(NVL(segment,SUMMARY))
  4. ---------------------------------------------------------------------------------
  5. FA        5314660
  6. Item 2        550
  7. PACKAGE        2606406
  8. PCBA        4980446
  9. SMT        3189386
  10.         16091448
  11. ---------------------------------------------------------------------------------
复制代码


使用如下语句在DB Server 的 Loading非常低的时候,RUN40次平均用时6.3488秒
在正常Loading的时候在11秒到25秒之间

  1. SELECT segment,SUM(qty) FROM
  2. tablename
  3. GROUP BY segment
  4. ---------------------------------------------------------------------------------
  5. FA        5314660
  6. Item 2        550
  7. PACKAGE        2606406
  8. PCBA        4980446
  9. SMT        3189386
  10. ---------------------------------------------------------------------------------
复制代码


我不明白相同的结果使用rollup还多做了运算,为什么速度反而快这么多?

想请教一下看各位有什么看法。谢谢

附上执行计划如下:


  1. SQL>; set autot on
  2. SQL>; SELECT NVL(segment,'SUMMARY') AS segment,SUM(qty) FROM tablename
  3.   2  GROUP BY ROLLUP(NVL(segment,'SUMMARY'));

  4. SEGMENT         SUM(QTY)                                                      
  5. --------------- ----------                                                      
  6. FA                 5314660                                                      
  7. Item 2                 550                                                      
  8. PACKAGE            2606406                                                      
  9. PCBA               4980446                                                      
  10. SMT                3189386                                                      
  11.                   16091448                                                      

  12. 已选择6行。


  13. Execution Plan
  14. ----------------------------------------------------------                     
  15.    0      SELECT STATEMENT Optimizer=FIRST_ROWS (Cost=7817 Card=120559         
  16.           7 Bytes=26523134)                                                     
  17.                                                                                 
  18.    1    0   SORT (GROUP BY ROLLUP) (Cost=7817 Card=1205597 Bytes=26523         
  19.           134)                                                                  
  20.                                                                                 
  21.    2    1     TABLE ACCESS (FULL) OF 'TABLENAME' (Cost=2241 Card=1205597         
  22.            Bytes=26523134)                                                      
  23.                                                                                 




  24. Statistics
  25. ----------------------------------------------------------                     
  26.           0  recursive calls                                                   
  27.          12  db block gets                                                      
  28.       14760  consistent gets                                                   
  29.           0  physical reads                                                     
  30.           0  redo size                                                         
  31.         379  bytes sent via SQL*Net to client                                   
  32.          57  bytes received via SQL*Net from client                             
  33.           2  SQL*Net roundtrips to/from client                                 
  34.           2  sorts (memory)                                                     
  35.           0  sorts (disk)                                                      
  36.           6  rows processed                                                     

  37. SQL>; SELECT segment,SUM(qty) FROM tablename
  38.   2  GROUP BY segment;

  39. SEGMENT         SUM(QTY)                                                      
  40. --------------- ----------                                                      
  41. FA                 5314660                                                      
  42. Item 2                 550                                                      
  43. PACKAGE            2606406                                                      
  44. PCBA               4980446                                                      
  45. SMT                3189386                                                      


  46. Execution Plan
  47. ----------------------------------------------------------                     
  48.    0      SELECT STATEMENT Optimizer=FIRST_ROWS (Cost=826 Card=1205597         
  49.            Bytes=26523134)                                                      
  50.                                                                                 
  51.    1    0   SORT (GROUP BY NOSORT) (Cost=826 Card=1205597 Bytes=265231         
  52.           34)                                                                  
  53.                                                                                 
  54.    2    1     TABLE ACCESS (BY INDEX ROWID) OF 'TABLENAME' (Cost=826 Car         
  55.           d=1205597 Bytes=26523134)                                             
  56.                                                                                 
  57.    3    2       INDEX (FULL SCAN) OF 'IDX2_72QSY' (NON-UNIQUE) (Cost=2         
  58.           6 Card=1205597)                                                      
  59.                                                                                 




  60. Statistics
  61. ----------------------------------------------------------                     
  62.           0  recursive calls                                                   
  63.           0  db block gets                                                      
  64.      195228  consistent gets                                                   
  65.           0  physical reads                                                     
  66.           0  redo size                                                         
  67.         368  bytes sent via SQL*Net to client                                   
  68.         152  bytes received via SQL*Net from client                             
  69.           3  SQL*Net roundtrips to/from client                                 
  70.           1  sorts (memory)                                                     
  71.           0  sorts (disk)                                                      
  72.           5  rows processed                                                     

复制代码

论坛徽章:
0
2 [报告]
发表于 2005-03-10 02:45 |只看该作者

奇怪。请帮忙分析一下为什么Rollup比简单SUM速度还快。

The execution plans makes the difference.
One is full table scan + sort while the other is full index scan then table access by rowid + non sort.

From the output is looks that you have an index on the segment column, and it only has a few distinct values.
The ratio is 6/17000000.

This index is unselective and you should drop it.

论坛徽章:
0
3 [报告]
发表于 2005-03-10 09:26 |只看该作者

奇怪。请帮忙分析一下为什么Rollup比简单SUM速度还快。

谢谢sshd的解释。不过是我没有解释清楚意思。执行计划我有看。
我疑惑的是如此相似的查询为什么Ora会采取这样两种执行计划。
Ora的选择标准是什么?
为什么使用了rollup和不使用会关联到Index的抉择
谢谢。。。

论坛徽章:
0
4 [报告]
发表于 2005-03-10 14:48 |只看该作者

奇怪。请帮忙分析一下为什么Rollup比简单SUM速度还快。

In both SQLs, oracle need to sort on segment.

case1:
GROUP BY ROLLUP(NVL(segment,SUMMARY))
the index on segment will not be used because functions are applied to segment, thus oracle will do full table scan, then sort on segment

case 2)
GROUP BY segment
the index on segment will be used to access the table, and the results are in accending or decending order (since the leaf level of the index tree are sorted by segment ), no more sorts are needed

Since the index on tablename(segment ) is unselective, it's basically is useless, and you will need to drop it.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP