SQL 语句优化--OR 语句优化案例
2008-09-23 16:53
281 查看
从上海来到温州,看了前几天监控的sql语句和数据变化,发现有一条语句的io次数很大,达到了150万次IO,而两个表的数据也就不到20万,为何有如此多的IO次数,下面是执行语句:
select ws.nodeid,wi.laststepid,wi.curstepid from Workflowinfo wi,
Workflowstep ws where ws.workflowid='402881db1b441e6f011c0cff320e4766' and (wi.laststepid = ws.id or (wi.curstepid = ws.id and isreceived=1 and issubmited =1))
表 'workflowstep'。扫描计数 1,逻辑读取 23 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Worktable'。扫描计数 4,逻辑读取 1490572 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'workflowinfo'。扫描计数 4,逻辑读取 12208 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
这里发现:主要是嵌套循环算法占的开销最大。个人感觉是“Or”引起的性能问题,后来根据业务逻辑改写。如下:
where ws.workflowid='402881db1b441e6f011c0cff320e4766' and (wi.laststepid = ws.id)
union all
select ws.nodeid,wi.laststepid,wi.curstepid from Workflowinfo wi, Workflowstep ws where ws.workflowid='402881db1b441e6f011c0cff320e4766' and (wi.curstepid = ws.id and isreceived=1 and issubmited =1)
表 'workflowinfo'。扫描计数 36,逻辑读取 142 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'workflowstep'。扫描计数 2,逻辑读取 46 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
执行计划如下:
这里发现:成本不在是嵌套循环上的开销了,IO次数大大减少。
对于类似的语句,可以将其改写成”Union“ 或”Union All“ 语句。
select ws.nodeid,wi.laststepid,wi.curstepid from Workflowinfo wi,
Workflowstep ws where ws.workflowid='402881db1b441e6f011c0cff320e4766' and (wi.laststepid = ws.id or (wi.curstepid = ws.id and isreceived=1 and issubmited =1))
执行IO统计结果如下:
(22 行受影响)表 'workflowstep'。扫描计数 1,逻辑读取 23 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Worktable'。扫描计数 4,逻辑读取 1490572 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'workflowinfo'。扫描计数 4,逻辑读取 12208 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
执行计划如下:
这里发现:主要是嵌套循环算法占的开销最大。个人感觉是“Or”引起的性能问题,后来根据业务逻辑改写。如下:
语句修改如下:
select ws.nodeid,wi.laststepid,wi.curstepid from Workflowinfo wi, Workflowstep wswhere ws.workflowid='402881db1b441e6f011c0cff320e4766' and (wi.laststepid = ws.id)
union all
select ws.nodeid,wi.laststepid,wi.curstepid from Workflowinfo wi, Workflowstep ws where ws.workflowid='402881db1b441e6f011c0cff320e4766' and (wi.curstepid = ws.id and isreceived=1 and issubmited =1)
查询IO次数如下:
(22 行受影响)表 'workflowinfo'。扫描计数 36,逻辑读取 142 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'workflowstep'。扫描计数 2,逻辑读取 46 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
执行计划如下:
这里发现:成本不在是嵌套循环上的开销了,IO次数大大减少。
总结:
这里通过改写”OR“语句成“Union”语句,性能大大提高,用了or语句,数据库优化器无法优化,这里都是用的“嵌套循环算法”,但是使用方式不一样,同样得到不同的结果。对于类似的语句,可以将其改写成”Union“ 或”Union All“ 语句。
相关文章推荐
- SQL 语句优化--OR 语句优化案例
- SQL语句优化一例 row_number not in or
- mysql sql语句优化案例 依靠主要性能指标来判断
- 性能优化分析案例---解决SQL语句过度消耗CPU问题
- 经典案例:如何优化Oracle使用DBlink的SQL语句
- SQL 语句优化 案例1
- SQL语句常见优化十大案例
- Oracle SQL 'or' 的优化,最近的案例一则。
- Sql语句优化之explan分析案例
- SQL语句常见优化十大案例
- 典型的SQL语句优化案例
- 对于sql语句or优化的一些看法
- SQL 语句优化--IN语句优化案例
- SQL 语句优化--IN语句优化案例
- SQL 语句优化--IN语句优化案例
- sql优化案例:oracle子查询的or 转为 union all以提升查询效率
- 数据库性能优化分析案例---解决SQL语句过度消耗CPU问题
- mysql优化sql语句
- oracle sql语句性能优化
- mysql数据库sql语句的一些常用优化方法