查看: 3631|回复: 10

[性能调整] SQL语句优化,求解!

[复制链接]
认证徽章
论坛徽章:
19
2009架构师大会纪念徽章
日期:2014-08-04 09:33:532010系统架构师大会纪念
日期:2014-08-04 09:33:532011系统架构师大会纪念章
日期:2014-08-04 09:33:532012系统架构师大会纪念章
日期:2014-08-04 09:33:532013系统架构师大会纪念章
日期:2014-08-04 09:33:532014系统架构师大会纪念章
日期:2014-08-04 09:33:53宝马
日期:2014-07-14 15:49:05秀才
日期:2015-07-31 09:12:09沸羊羊
日期:2015-03-04 14:51:522015年新春福章
日期:2015-03-06 11:58:18
发表于 2010-6-10 12:00 | 显示全部楼层 |阅读模式
SELECT count(*)
  FROM table1 b
  left join table2 e on b.id = e.id
  left join table3 t on b.id = t.id
where b.pid = 'CNFGTNTS86ae114554c34531a1920c4984d45940'
   and b.type = 1;

table1\table2\table3分别有1428089\1428089\1425358条记录

查询计划:
SELECT STATEMENT, GOAL = CHOOSE                        518        1        740                               
SORT AGGREGATE                                1        740                               
  NESTED LOOPS OUTER                        518        811        600140                               
   NESTED LOOPS OUTER                        518        515        369770                               
    TABLE ACCESS BY INDEX ROWID        C01        table1        3        515        348655                               
     INDEX RANGE SCAN        CC01        IND_table1_CRETIME        2        82                                       
    INDEX RANGE SCAN        CC01        IND_table3        1        1        41                               
   INDEX UNIQUE SCAN        CC01        PK_table2                2        44               

现在执行时间是要2分钟多,
现在在table1上创建了索引:
IND_table1_CRETIME(type,pid);
表table2对id列创建了索引,表table3对id创建了索引,
查询条件筛选的记录条数为总数的90%多,,
请问怎么优化好点啊,,!~~
论坛徽章:
3
祖国60周年纪念徽章
日期:2009-10-09 08:28:002011新春纪念徽章
日期:2011-02-18 11:43:33ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
发表于 2010-6-10 12:42 | 显示全部楼层
count(*) 改为 count(b.id)

使用道具 举报

回复
认证徽章
论坛徽章:
19
2009架构师大会纪念徽章
日期:2014-08-04 09:33:532010系统架构师大会纪念
日期:2014-08-04 09:33:532011系统架构师大会纪念章
日期:2014-08-04 09:33:532012系统架构师大会纪念章
日期:2014-08-04 09:33:532013系统架构师大会纪念章
日期:2014-08-04 09:33:532014系统架构师大会纪念章
日期:2014-08-04 09:33:53宝马
日期:2014-07-14 15:49:05秀才
日期:2015-07-31 09:12:09沸羊羊
日期:2015-03-04 14:51:522015年新春福章
日期:2015-03-06 11:58:18
发表于 2010-6-10 14:33 | 显示全部楼层

回复 #2 csbwolf10 的帖子

不行啊,还是很慢的!。。。

使用道具 举报

回复
论坛徽章:
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
发表于 2010-6-10 14:37 | 显示全部楼层
原帖由 csbwolf10 于 2010-6-10 12:42 发表
count(*) 改为 count(b.id)

和这个基本没有关系!

收集下统计信息看看,nested loop对数据量大效果不是很好!

使用道具 举报

回复
认证徽章
论坛徽章:
19
2009架构师大会纪念徽章
日期:2014-08-04 09:33:532010系统架构师大会纪念
日期:2014-08-04 09:33:532011系统架构师大会纪念章
日期:2014-08-04 09:33:532012系统架构师大会纪念章
日期:2014-08-04 09:33:532013系统架构师大会纪念章
日期:2014-08-04 09:33:532014系统架构师大会纪念章
日期:2014-08-04 09:33:53宝马
日期:2014-07-14 15:49:05秀才
日期:2015-07-31 09:12:09沸羊羊
日期:2015-03-04 14:51:522015年新春福章
日期:2015-03-06 11:58:18
发表于 2010-6-10 15:00 | 显示全部楼层

回复 #4 dingjun123 的帖子

这是生产库,我怕收集了会对其他地方引起性能影响,有没有其他方法,
版本:9.2.0.5

使用道具 举报

回复
论坛徽章:
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
发表于 2010-6-10 15:22 | 显示全部楼层
原帖由 qqmengxue 于 2010-6-10 15:00 发表
这是生产库,我怕收集了会对其他地方引起性能影响,有没有其他方法,
版本:9.2.0.5

加hint试试,用use_hash

使用道具 举报

回复
论坛徽章:
11
授权会员
日期:2005-10-30 17:05:33ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44会员2007贡献徽章
日期:2007-09-26 18:42:10嫦娥
日期:2006-09-26 17:31:50生肖徽章:马
日期:2006-09-07 17:03:44生肖徽章:狗
日期:2006-09-07 10:14:30生肖徽章:鼠
日期:2006-09-06 21:17:11生肖徽章:兔
日期:2006-09-06 21:16:33ITPUB元老
日期:2006-08-24 11:59:54会员2006贡献徽章
日期:2006-04-17 13:46:34
发表于 2010-6-10 15:25 | 显示全部楼层
试试这种:
1.
SELECT count(*)
  FROM ( select * from  table1  where  table1 .pid = 'CNFGTNTS86ae114554c34531a1920c4984d45940' and  table1 .type = 1)  b
  left join table2 e on b.id = e.id
  left join table3 t on b.id = t.id
;

2. 把"b.pid = ?? and b.type = ??" 条件上调到两个LEFT JOIN的ON后面, 具体语法我记不清,你自己查下就知道了


前提是"b.pid = ?? and b.type = ??" 条件筛选掉了大部分别名为B表的记录

[ 本帖最后由 sealight 于 2010-6-10 15:28 编辑 ]

使用道具 举报

回复
求职 : 数据库管理员
认证徽章
论坛徽章:
32
生肖徽章2007版:狗
日期:2009-07-20 17:10:18茶鸡蛋
日期:2013-05-23 16:34:43茶鸡蛋
日期:2013-07-19 14:39:22ITPUB社区千里马徽章
日期:2013-08-22 09:58:03雪铁龙
日期:2013-08-23 13:04:11林肯
日期:2013-09-04 14:07:20兰博基尼
日期:2013-09-16 13:45:20马上有钱
日期:2014-05-14 14:07:392014年世界杯参赛球队: 波黑
日期:2014-07-03 13:24:39马上有对象
日期:2014-10-30 14:04:32
发表于 2010-6-10 15:28 | 显示全部楼层
b.id列可选择度高吗?若id列可选择度高,考虑在该列上创建索引试试。另外table1的记录数也不算少,建议count(*)修改为count(rowid)。查询条件筛选的记录条数为总数的90%多,这时候走索引扫描的效率还不如走全表扫描的效率高。

使用道具 举报

回复
论坛徽章:
0
发表于 2010-6-24 03:38 | 显示全部楼层
SELECT/*+ full(b) */count(*)
  FROM table1 b
  left join table2 e on b.id = e.id
  left join table3 t on b.id = t.id
where b.pid = 'CNFGTNTS86ae114554c34531a1920c4984d45940'
   and b.type = 1;

先用上面的试试。table1用全表扫描
再者你用的cost优化器,但是你的统计信息不行。统计一下吧。

使用道具 举报

回复
论坛徽章:
86
2015中国数据库技术大会纪念徽章
日期:2015-04-24 16:04:24马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11优秀写手
日期:2013-12-18 09:29:11日产
日期:2013-10-17 08:44:39马自达
日期:2013-08-26 16:28:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-23 16:55:51马上有房
日期:2014-02-19 11:55:14
发表于 2010-6-24 08:13 | 显示全部楼层
还是收集一下统计信息更好。
变坏的情况毕竟不多,特殊问题特殊处理。
否则,出一个慢的SQL你都去改应用?

使用道具 举报

回复

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

本版积分规则 发表回复

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