Chinaunix首页 | 论坛 | 博客
  • 博客访问: 18672566
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类: Mysql/postgreSQL

2008-05-19 19:48:52

案例:

发现应用程序慢,开始把目光放在检查商业逻辑的SQL上面,觉得没什么问题,但是执行时间大大超出我的预期。

后来询问开发人员,原来最初会取工单表里面的最近工单时间,最早工单时间来做对比。

根据经验,对索引字段做MAX或者MIN是很快的,因为索引是有序,优化器直接到索引头或者尾部去取rowid就可以了。

但是打开程序一看,SQLpreparement里面的句子是这样的:

select min(billtime),MAX(billtime) from billcontent

觉得有问题了,一看执行计划,恍然大悟:

Execution Plan

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

Plan hash value: 1499044795

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

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |

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

| 0 | SELECT STATEMENT | | 1 | 8 | 5126 (3)| 00:01:02 | | |

| 1 | SORT AGGREGATE | | 1 | 8 | | | | |

| 2 | PARTITION RANGE SINGLE| | 7653K| 58M| 5126 (3)| 00:01:02 | 1 | 1 |

| 3 | PARTITION LIST ALL | | 7653K| 58M| 5126 (3)| 00:01:02 | 1 | 21 |

| 4 | INDEX FAST FULL SCAN| IDX_ANALYSE_CONTENT_2 | 7653K| 58M| 5126 (3)| 00:01:02 | 1 | 21 |

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

Statistics

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

26745 consistent gets

是INDEX FAST FULL SCAN,26745 个一致读,5126 的Cost,大概查了一下,该索引拥有27632个块,现在对索引做了完全扫描。

对于一致读和Cost的计算,这里暂不多述。

只查一个极限值话:

select min(billtime) from billcontent;

Execution Plan

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

Plan hash value: 4137395070

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

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |

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

| 0 | SELECT STATEMENT | | 1 | 8 | 3 (0)| 00:00:01 | | |

| 1 | SORT AGGREGATE | | 1 | 8 | | | | |

| 2 | PARTITION RANGE SINGLE | | 7653K| 58M| 3 (0)| 00:00:01 | 1 | 1 |

| 3 | PARTITION LIST ALL | | 7653K| 58M| 3 (0)| 00:00:01 | 1 | 21 |

| 4 | INDEX FULL SCAN (MIN/MAX)| IDX_ANALYSE_CONTENT_2 | 7653K| 58M| 3 (0)| 00:00:01 | 1 | 21 |

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

Statistics

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

42 consistent gets

计划是INDEX FULL SCAN (MIN/MAX),(MIN/MAX)表明只会访问索引的头或尾,开销大大减小,只有42个一致读和极低的Cost,正常情况只能是

这个的两倍多。

马上动手改为:

SELECT

(select min(calltime) from analyse_content ),

(select MAX(calltime) from analyse_content )

FROM dual

Execution Plan

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

Plan hash value: 2326664376

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

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |

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

| 0 | SELECT STATEMENT | | 1 | | 2 (0)| 00:00:01 | | |

| 1 | SORT AGGREGATE | | 1 | 8 | | | | |

| 2 | PARTITION RANGE SINGLE | | 7653K| 58M| 3 (0)| 00:00:01 | 1 | 1 |

| 3 | PARTITION LIST ALL | | 7653K| 58M| 3 (0)| 00:00:01 | 1 | 21 |

| 4 | INDEX FULL SCAN (MIN/MAX)| IDX_ANALYSE_CONTENT_2 | 7653K| 58M| 3 (0)| 00:00:01 | 1 | 21 |

| 5 | SORT AGGREGATE | | 1 | 8 | | | | |

| 6 | PARTITION RANGE SINGLE | | 7653K| 58M| 3 (0)| 00:00:01 | 1 | 1 |

| 7 | PARTITION LIST ALL | | 7653K| 58M| 3 (0)| 00:00:01 | 1 | 21 |

| 8 | INDEX FULL SCAN (MIN/MAX)| IDX_ANALYSE_CONTENT_2 | 7653K| 58M| 3 (0)| 00:00:01 | 1 | 21 |

| 9 | FAST DUAL | | 1 | | 2 (0)| 00:00:01 | | |

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

Statistics

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

84 consistent gets

完美解决。

其实这个问题很小,这个SQL人人都会写,但是很多开发人员,在写这种SQL的时候不会去思考结果产生的过程,以实现为原则,在他们眼中仍然是黑盒。在测试过程中也没有仔细观察效率,在测试表数据较少,人眼感觉不出来问题,一在生产库跑就越来越慢。

所以,无论是开发和DBA多数据库的执行机制和原理,是没有害处的。

阅读(470) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~