Sql Server 的性能测试数据的陷阱
数据库的性能测试可以帮助你提前知道你的系统的负载能力,可以帮助你改进系统的实施或设计,可以帮助你确定一些设计和编程原则. 但是,这里面也有陷阱. 如果不小心,你会自己把自己陷进去,却最终不明白是什么原因. 这里,我拿一位先生为例,来看看他怎么自己把自己搞糊涂的.
最近, 想起在存储过程中究竟是使用临时表还是使用表变量对性能更为有利的问题. 我想这个问题的关键涉及到数据库是否对其进行transaction 管理的问题, 如果进行transaction 管理, 那么在改变表中的记录时就会使用 write-ahead transaction log 策略, 这样数据改变操作就会变慢. 所以, 如果数据库engine仅对一种类型的表进行事物管理, 那么使用不同类型的表就会体现出性能差别. 于是, 我就在网上搜了一下, 还真查出一篇特别对口的文章, Temporary Tables vs. Table Variables and Their Effect on SQL Server Performance.
总结Tsuranoff的这篇文章, 关于临时表和表变量, 理论上说, 有三点:
1. 数据库engine对临时表进行事务管理,但不对表变量进行事务管理.
2. 表变量是完全局域的,因此,不需要任何的locking.
3. 表变量相对临时表而言,比较少引起重编译
然后,Tsuranoff便展示了性能测试的结果,转录如下:
N
T1
T2
T3
V1
V2
10
0.5
0.5
5.3
0.2
0.2
100
2
1.2
6.4
61.8
2.5
1000
9.3
8.5
13.5
168
140
10000
67.4
79.2
71.3
17133
13910
100000
700
794
659
Too long!
Too long!
1000000
10556
8673
6440
Too long!
Too long!
Table 2: Using SQL Server 2005 (time in ms).
为了读者阅读方便,我这里给出上表的解释:
1. T1, T2, T3, V1, V2代表了不同的存储过程,他们的逻辑和功能完全相同,仅仅是实现手法上略有差别. T1, T2, T3对应使用临时表的存储过程,其差别在于, T1不使用索引, T2使用预先定义的索引,T3先对临时表倒入数据,在进行查询前再建索引. V1使用表变量,但不使用索引,V2使用表变量并使用索引. "N"一列的数值是试验时对这些存储过程所采用的参数.
2. 结果显示,使用表变量的存储过程的性能并不比使用临时表的存储过程性能更好,相反,当输入参数N(即处理的行数)变大时,性能完全变坏.
毫无疑问,试验数据和理论推测的结果相反. 然而作者不去追究其深层的原因,就糊里糊涂的给出一堆结论. 可想而知,连数据都是错的,那给出的结论还不误人子弟吗? 这里就不重复他的结论了.
当我看到这些数
相关文档:
#Region " 命名空间 "
Imports System.Data
Imports System.Data.SqlClient
#End Region
Public Class DBCommon
Implements IDisposable
#Region " 成员变量 "
Private conn As SqlConnection
Private cmd As SqlCommand
Private trans As SqlTransaction
#End Region
#Region " 构造函数 "
......
有时在做程序时,测试时的数据,要拿像用户演示,数据库的附加是最直接的办法,但若从SQL Server 2005转向2000导出麻烦,内容也多,生成SQL语句是最好的办法,也是在网上找的工具,mssql2导出非常方便,担心我以后难得找所以放在这里,以备后用。 ......
具体实现如下:
SQL> select count(*) from v$session #连接数
SQL> Select count(*) from v$session where status='ACTIVE' #并发连接数
SQL> show parameter processes #最大连接
SQL> alter system set processes = value scope = spfile;重启数据库 #修改连接 ......
由于代码过于简单,直接贴出:
SqlDataSourceEnumerator SseInstance = SqlDataSourceEnumerator.Instance;
//ServerName:服务器名;
//InstanceName:实例名;
//IsClustered:是否为群集服务器的一部分;
//Version:版本,8.*是SQL 2000,9.*是SQL 2005
DataTable DtSqlInstance = SseInstance.GetDataSources();
注: ......