当前位置: 首页 > 图文教程 > 数据库 > MSSQL > 用一个案例讲解应用程序越来越慢的原因

MSSQL
SQL Server中容易混淆的数据类型
影响SQL Server性能的主要原因
浅谈SQL Server查询优化器中的JOIN算法
怎样缩小SQL Server数据库日志文件
SQL Server 2005最值得你升级的10个理由
SQL Server 商务智能特性对比
SQL Server 2005 SP1的新特性
怎样使用SQL Server来过滤数据
在SQL Server中处理空值时涉及的三个问题
怎样才能保护好 SQL Server 数据库
SQL SERVER数据库口令的脆弱性
SQL Server中的动态和静态内存分配
SQL存储过程学习:特殊的存储过程-触发器
几条常见的数据库分页 SQL 语句
SQL Server 2008服务器合并功能介绍
SQL Server数据库开发的二十一条军规
SQL Server 2008 的管理能力
快速删除重复记录,SQL Server如何实现?
将MySQL数据导入到Sql Server中
SQL Server和MySQL的安全性分析

MSSQL 中的 用一个案例讲解应用程序越来越慢的原因


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-17   浏览: 88 ::
收藏到网摘: n/a

这篇论坛文章(赛迪网技术社区)主要介绍了一个导致应用程序越来越慢的的实际案例,详细内容请参考下文:

案例:

发现应用程序慢,开始把目光放在检查商业逻辑的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多学习数据库的执行机制和原理,是没有害处的。