查看: 5275|回复: 20

[性能调整] 帮忙看个sql 优化句子 谢

[复制链接]
论坛徽章:
4
奥运会纪念徽章:射击
日期:2008-10-24 13:23:422010新春纪念徽章
日期:2010-03-01 11:19:072010数据库技术大会纪念徽章
日期:2010-05-13 09:34:23ITPUB十周年纪念徽章
日期:2011-11-01 16:21:15
发表于 2011-7-22 09:41 | 显示全部楼层 |阅读模式
select ((v.yvalue * 300) / (u.xvalue * 50)), u.xtime
  from (select x.index_value xvalue, substr(x.update_time, 1, 14) xtime
        
          from tb_indexs x
         where x.id in (select min(a.id)
                          from tb_indexs a
                         where a.code = 'HSI'
                           and a.update_time > 20110701000000
                           and a.update_time < 20110722000000
                         group by a.update_time)) u,
      
       (select y.index_value yvalue, substr(y.update_time, 1, 14) ytime
        
          from tb_indexs y
         where y.id in (select min(b.id)
                          from tb_indexs b
                         where b.code = '000300'
                           and b.update_time > 20110701000000
                           and b.update_time < 20110722000000
                         group by b.update_time)) v
where u.xtime = v.ytime
order by u.xtime


后面是加了一个update_time 的索引的结果 , cost很小 但执行起来很慢
表用dbms_stat.gather_table_stats  做了cascade的分析

[ 本帖最后由 ouyangzi 于 2011-7-22 10:06 编辑 ]
2011-07-22_093630.jpg
2011-07-22_100456.jpg
论坛徽章:
1088
金色在线徽章
日期:2007-04-25 04:02:08金色在线徽章
日期:2007-06-29 04:02:43金色在线徽章
日期:2007-03-11 04:02:02在线时间
日期:2007-04-11 04:01:02在线时间
日期:2007-04-12 04:01:02在线时间
日期:2007-03-07 04:01:022008版在线时间
日期:2010-05-01 00:01:152008版在线时间
日期:2011-05-01 00:01:342008版在线时间
日期:2008-06-03 11:59:43ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30
发表于 2011-7-22 09:51 | 显示全部楼层
主要是merge join cartesian

使用道具 举报

回复
论坛徽章:
8
数据库板块每日发贴之星
日期:2009-06-12 01:01:02数据库板块每日发贴之星
日期:2009-06-21 01:01:01ITPUB9周年纪念徽章
日期:2010-10-08 09:32:272010广州亚运会纪念徽章:游泳
日期:2010-11-12 16:42:092011新春纪念徽章
日期:2011-02-18 11:42:502010广州亚运会纪念徽章:三项全能
日期:2011-02-26 13:07:50咸鸭蛋
日期:2011-08-30 15:51:05ITPUB十周年纪念徽章
日期:2011-11-01 16:25:22
发表于 2011-7-22 09:59 | 显示全部楼层
你要把谓词部分的信息也贴出来,才好观察嘛。merge join cartesian的效率估计不会高。要看看filter部分哈。

使用道具 举报

回复
论坛徽章:
1088
金色在线徽章
日期:2007-04-25 04:02:08金色在线徽章
日期:2007-06-29 04:02:43金色在线徽章
日期:2007-03-11 04:02:02在线时间
日期:2007-04-11 04:01:02在线时间
日期:2007-04-12 04:01:02在线时间
日期:2007-03-07 04:01:022008版在线时间
日期:2010-05-01 00:01:152008版在线时间
日期:2011-05-01 00:01:342008版在线时间
日期:2008-06-03 11:59:43ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30
发表于 2011-7-22 10:00 | 显示全部楼层
我觉得LZ可以试试重新收集下统计信息,貌似有点问题

使用道具 举报

回复
论坛徽章:
4
奥运会纪念徽章:射击
日期:2008-10-24 13:23:422010新春纪念徽章
日期:2010-03-01 11:19:072010数据库技术大会纪念徽章
日期:2010-05-13 09:34:23ITPUB十周年纪念徽章
日期:2011-11-01 16:21:15
 楼主| 发表于 2011-7-22 10:17 | 显示全部楼层
SQL> desc tb_indexs
Name        Type          Nullable Default Comments
----------- ------------- -------- ------- --------
ID          NUMBER                                 
CODE        VARCHAR2(50)  Y                        
INDEX_VALUE NUMBER(20,10) Y                        
UPDATE_TIME NUMBER        Y

使用道具 举报

回复
论坛徽章:
5
ITPUB9周年纪念徽章
日期:2010-10-08 09:28:51数据库板块每日发贴之星
日期:2011-07-22 01:01:02蜘蛛蛋
日期:2011-08-24 14:10:13ITPUB十周年纪念徽章
日期:2011-11-01 16:24:042012新春纪念徽章
日期:2012-01-04 11:54:26
发表于 2011-7-22 10:24 | 显示全部楼层
SQL优化最好用SQLPLUS, 用工具不好看filter信息
不看filter信息,只贴一个访问路径的人 一看就没做过SQL优化

加QQ 692162374 ,帮你看看

使用道具 举报

回复
论坛徽章:
1088
金色在线徽章
日期:2007-04-25 04:02:08金色在线徽章
日期:2007-06-29 04:02:43金色在线徽章
日期:2007-03-11 04:02:02在线时间
日期:2007-04-11 04:01:02在线时间
日期:2007-04-12 04:01:02在线时间
日期:2007-03-07 04:01:022008版在线时间
日期:2010-05-01 00:01:152008版在线时间
日期:2011-05-01 00:01:342008版在线时间
日期:2008-06-03 11:59:43ITPUB年度最佳技术原创精华奖
日期:2013-03-22 13:18:30
发表于 2011-7-22 10:25 | 显示全部楼层
收集下统计信息啊,应该是统计信息不准确造成的,从计划里能看出端倪,你那计划,oracle就走笛卡尔积了,然后导致buffer sort

使用道具 举报

回复
论坛徽章:
4
奥运会纪念徽章:射击
日期:2008-10-24 13:23:422010新春纪念徽章
日期:2010-03-01 11:19:072010数据库技术大会纪念徽章
日期:2010-05-13 09:34:23ITPUB十周年纪念徽章
日期:2011-11-01 16:21:15
 楼主| 发表于 2011-7-22 10:43 | 显示全部楼层
SQL> select *  from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 573554298
--------------------------------------------------------------------------------
| Id  | Operation                         | Name            | Rows  | Bytes | Co
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                  |                 |     1 |    54 |
|   1 |  SORT ORDER BY                    |                 |     1 |    54 |
|   2 |   NESTED LOOPS                    |                 |     1 |    54 |
|   3 |    MERGE JOIN CARTESIAN           |                 |     1 |    33 |
|   4 |     NESTED LOOPS                  |                 |     1 |    27 |
|   5 |      VIEW                         | VW_NSO_2        |     1 |     6 |
|   6 |       HASH GROUP BY               |                 |     1 |    26 |
|   7 |        TABLE ACCESS BY INDEX ROWID| TB_INDEXS       |     1 |    26 |
|*  8 |         INDEX RANGE SCAN          | IDX_UPDATE_TIME |     1 |       |
|   9 |      TABLE ACCESS BY INDEX ROWID  | TB_INDEXS       |     1 |    21 |
|* 10 |       INDEX UNIQUE SCAN           | PK_INDEXS       |     1 |       |
|  11 |     BUFFER SORT                   |                 |     1 |     6 |
|  12 |      VIEW                         | VW_NSO_1        |     1 |     6 |
|  13 |       HASH GROUP BY               |                 |     1 |    26 |
|  14 |        TABLE ACCESS BY INDEX ROWID| TB_INDEXS       |     1 |    26 |
|* 15 |         INDEX RANGE SCAN          | IDX_UPDATE_TIME |     1 |       |
|* 16 |    TABLE ACCESS BY INDEX ROWID    | TB_INDEXS       |     1 |    21 |
|* 17 |     INDEX UNIQUE SCAN             | PK_INDEXS       |     1 |       |
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   8 - access("A"."CODE"='HSI' AND "A"."UPDATE_TIME">20110701000000 AND
              "A"."UPDATE_TIME"<20110722000000)
  10 - access("X"."ID"="$nso_col_1")
  15 - access("B"."CODE"='000300' AND "B"."UPDATE_TIME">20110701000000 AND
              "B"."UPDATE_TIME"<20110722000000)
  16 - filter(SUBSTR(TO_CHAR("X"."UPDATE_TIME"),1,14)=SUBSTR(TO_CHAR("Y"."UPDATE
              )
  17 - access("Y"."ID"="$nso_col_1")

36 rows selected

Executed in 1.469 seconds

使用道具 举报

回复
招聘 : Java研发
认证徽章
论坛徽章:
71
马上加薪
日期:2014-02-19 11:55:14蜘蛛蛋
日期:2012-12-26 18:16:01茶鸡蛋
日期:2012-11-16 08:12:48ITPUB 11周年纪念徽章
日期:2012-10-09 18:05:07奥运会纪念徽章:网球
日期:2012-08-23 14:58:08奥运会纪念徽章:沙滩排球
日期:2012-07-19 17:28:14版主2段
日期:2012-07-07 02:21:02咸鸭蛋
日期:2012-03-23 18:17:482012新春纪念徽章
日期:2012-02-13 15:13:512012新春纪念徽章
日期:2012-02-13 15:13:51
发表于 2011-7-22 11:00 | 显示全部楼层
("A"."CODE"='HSI' AND "A"."UPDATE_TIME">20110701000000 AND
              "A"."UPDATE_TIME"<20110722000000)
被评估为0行(或1行),统计信息可能不准确

min(update_time)、max(update_time)差距过大?

使用道具 举报

回复
论坛徽章:
4
奥运会纪念徽章:射击
日期:2008-10-24 13:23:422010新春纪念徽章
日期:2010-03-01 11:19:072010数据库技术大会纪念徽章
日期:2010-05-13 09:34:23ITPUB十周年纪念徽章
日期:2011-11-01 16:21:15
 楼主| 发表于 2011-7-22 11:05 | 显示全部楼层
这个表大概有60多万行
执行字句
select y.index_value yvalue, substr(y.update_time, 1, 14) ytime
11   from tb_indexs y
12           where y.id in (select min(b.id)
13                            from tb_indexs b
14                           where b.update_time < 20110722000000
15                             and b.update_time > 20110701000000
16                             and b.code = '000300'
17                           group by b.update_time)

大概有4万行结果   两个字句都差不多有这么大的数据量
cost显示只有13  不可靠
已多次执行过这个表的 统计分析

使用道具 举报

回复

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

本版积分规则 发表回复

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