查看: 4355|回复: 22

请教个SQL优化的问题,高手们帮忙

[复制链接]
论坛徽章:
0
发表于 2009-12-30 10:44 | 显示全部楼层 |阅读模式
这个SQL目前需要几小时才能执行完。。
SQL及执行计划如下:

SQL> select t.id,tt.term_name,t.device_id,t.speed,
  2      to_char(t.alarm_time,'yyyy-MM-dd hh24:mi:ss') alarm_time,tcase.max_speed
  3      from t_area_locrecord t ,t_speed_case tcase,t_terminal tt
  4      where
  5      tt.ent_code='empRoot'
  6      and
  7      tcase.id=t.case_id
  8      AND  
  9      t.device_id=tt.device_id
10      AND
11      t.ALARM_TIME>sysdate-1
12      and t.alarm_type=1
13      and t.speed>tcase.max_speed
14      and tt.device_id is not null
15  /
Elapsed: 00:00:00.00

Execution Plan
----------------------------------------------------------
Plan hash value: 1639185357

-------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                  | 56449 |  3803K| 88165   (1)| 00:17:38 |
|*  1 |  HASH JOIN                   |                  | 56449 |  3803K| 88165   (1)| 00:17:38 |
|   2 |   TABLE ACCESS FULL          | T_SPEED_CASE     |  2689 | 21512 |     7   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS BY INDEX ROWID| T_AREA_LOCRECORD | 14201 |   388K| 49700   (1)| 00:09:57 |
|   4 |    NESTED LOOPS              |                  |  1128K|    65M| 88144   (1)| 00:17:38 |
|*  5 |     TABLE ACCESS FULL        | T_TERMINAL       |    80 |  2640 |   504   (2)| 00:00:07 |
|*  6 |     INDEX RANGE SCAN         | INDEX_DEVICEID   | 78981 |       |   480   (1)| 00:00:06 |
-------------------------------------------------------------------------------------------------

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

   1 - access("TCASE"."ID"="T"."CASE_ID")
       filter("T"."SPEED">"TCASE"."MAX_SPEED")
   3 - filter(TO_NUMBER("T"."ALARM_TYPE")=1 AND "T"."ALARM_TIME">SYSDATE@!-1)
   5 - filter("TT"."ENT_CODE"='empRoot')
   6 - access("T"."DEVICE_ID"="TT"."DEVICE_ID")

Note
-----
   - 'PLAN_TABLE' is old version


每个表的数据量
SQL> select count(*) from T_AREA_LOCRECORD
  2  /

  COUNT(*)
----------
100790989

SQL> select count(*)from T_SPEED_CASE
  2  /

  COUNT(*)
----------
      2698

SQL> select count(*) from t_terminal
  2  /

  COUNT(*)
----------
    165941
招聘 : 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
发表于 2009-12-30 10:54 | 显示全部楼层
t.ALARM_TIME>sysdate-1
    ALARM_TIME是否有索引,符合条件的记录数是多少
   可试试将sysdate换成常数

使用道具 举报

回复
认证徽章
论坛徽章:
211
白羊座
日期:2016-03-22 08:17:34青年奥林匹克运动会-三人篮球
日期:2014-09-15 02:28:46青年奥林匹克运动会-射箭
日期:2014-09-15 01:42:34青年奥林匹克运动会-帆船
日期:2014-09-13 08:58:09青年奥林匹克运动会-三人篮球
日期:2014-09-13 05:28:31青年奥林匹克运动会-三人篮球
日期:2014-09-12 19:37:47青年奥林匹克运动会-手球
日期:2014-09-12 17:22:08青年奥林匹克运动会-拳击
日期:2014-09-10 06:22:35青年奥林匹克运动会-游泳
日期:2014-09-09 18:51:21青年奥林匹克运动会-手球
日期:2014-09-09 18:35:15
发表于 2009-12-30 10:55 | 显示全部楼层
嗯 學習中

使用道具 举报

回复
论坛徽章:
0
 楼主| 发表于 2009-12-30 11:04 | 显示全部楼层
ALARM_TIME上没有索引。
时间改成常数效果一样。

使用道具 举报

回复
论坛徽章:
9
2009新春纪念徽章
日期:2009-01-04 14:52:28祖国60周年纪念徽章
日期:2009-10-09 08:28:00ITPUB9周年纪念徽章
日期:2010-10-08 09:28:51蛋疼蛋
日期:2011-08-09 14:26:55ITPUB十周年纪念徽章
日期:2011-11-01 16:24:51ITPUB 11周年纪念徽章
日期:2012-10-09 18:09:19奥迪
日期:2013-09-12 15:57:042014年新春福章
日期:2014-02-18 16:43:09马上有钱
日期:2014-02-18 16:43:09
发表于 2009-12-30 11:05 | 显示全部楼层
有2个问题要看看:
1)TABLE ACCESS FULL        | T_TERMINAL ==》 5 - filter("TT"."ENT_CODE"='empRoot')

emproot的选择率很高? 如果很高,全表就让它全表,如果不高,看看是否为什么不用索引。
从执行计划看  TABLE ACCESS FULL        | T_TERMINAL       |    80 |  2640 |   504   (2)| 00:00:07 | 不过预估80行,应该用索引才对。
要么信息是错误的。
2)
NESTED LOOPS              |                  |  1128K|    65M| 88144   (1)| 00:17:38 |
|*  5 |     TABLE ACCESS FULL        | T_TERMINAL       |    80 |  2640 |   504   (2)| 00:00:07 |
|*  6 |     INDEX RANGE SCAN         | INDEX_DEVICEID  78981

如果预估的80是正确的,那么走LOOP也许是好的选择, 但是如果80是错的,那么看看HASH如何?

使用道具 举报

回复
论坛徽章:
0
 楼主| 发表于 2009-12-30 11:07 | 显示全部楼层
在ALARM_TIME上加了索引一样。

使用道具 举报

回复
论坛徽章:
120
现任管理团队成员
日期:2011-05-07 01:45:08乌索普
日期:2019-02-14 23:54:04
发表于 2009-12-30 11:17 | 显示全部楼层
select count(*) from t_terminal where "TT"."ENT_CODE"='empRoot'

?

使用道具 举报

回复
招聘 : 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
发表于 2009-12-30 11:20 | 显示全部楼层
原帖由 zergduan 于 2009-12-30 11:17 发表
select count(*) from t_terminal where "TT"."ENT_CODE"='empRoot'

?

估计80左右

使用道具 举报

回复
论坛徽章:
2
2010新春纪念徽章
日期:2010-01-04 08:33:082010新春纪念徽章
日期:2010-03-01 11:20:05
发表于 2009-12-30 11:35 | 显示全部楼层
1. 这些表及索引有多久没有分析过了?
2. 这个SQL以前的运行效率怎么样?
3.
tt.ent_code 可能需要建索引。
tt.device_id (可以试试建个索引)

看这里《TO_NUMBER("T"."ALARM_TYPE")=1》t.ALARM_TYPE是不是字符类型,试试t.alarm_type="1"看看。还要看看t.alarm_type的数据,根据多少个DICTINCT的值,看需要不需要建索引。"T"."ALARM_TIME" 应该建个索引。

使用道具 举报

回复
论坛徽章:
0
 楼主| 发表于 2009-12-30 11:40 | 显示全部楼层
表和索引刚分析过。

使用道具 举报

回复

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

本版积分规则 发表回复

SACC2019中国系统架构师大会

【数字转型 架构演进】SACC2019中国系统架构师大会,7折限时优惠重磅来袭!
2019年10月31日~11月2日第11届中国系统架构师大会(SACC2019)将在北京隆重召开。四大主线并行的演讲模式,1个主会场、20个技术专场、超千人参与的会议规模,100+来自互联网、金融、制造业、电商等领域的嘉宾阵容,将为广大参会者提供一场最具价值的技术交流盛会。

限时七折期:2019年8月31日前


----------------------------------------

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