面向程序员的数据库访问性能优化法则
“商机投资”通过精心收集,向本站投稿了9篇面向程序员的数据库访问性能优化法则,下面是小编为大家整理后的面向程序员的数据库访问性能优化法则,以供大家参考借鉴!
篇1:面向程序员的数据库访问性能优化法则
2.1、数据分页处理
一般数据分页方式有:
2.1.1、客户端(应用程序或浏览器)分页
将数据从应用服务器全部下载到本地应用程序或浏览器,在应用程序或浏览器内部通过本地代码进行分页处理
优点:编码简单,减少客户端与应用服务器网络交互次数
缺点:首次交互时间长,占用客户端内存
适应场景:客户端与应用服务器网络延时较大,但要求后续操作流畅,如手机GPRS,超远程访问(跨国)等等。
2.1.2、应用服务器分页
将数据从数据库服务器全部下载到应用服务器,在应用服务器内部再进行数据筛选。以下是一个应用服务器端Java程序分页的示例:
List list=executeQuery(“select * from employee order by id”);
Int count= list.size;
List subList= list.subList(10, 20);
优点:编码简单,只需要一次SQL交互,总数据与分页数据差不多时性能较好。
缺点:总数据量较多时性能较差。
适应场景:数据库系统不支持分页处理,数据量较小并且可控。
2.1.3、数据库SQL分页
采用数据库SQL分页需要两次SQL完成
一个SQL计算总数量
一个SQL返回分页后的数据
优点:性能好
缺点:编码复杂,各种数据库语法不同,需要两次SQL交互。
oracle数据库一般采用rownum来进行分页,常用分页语法有如下两种:
直接通过rownum分页:
select * from (
select a.*,rownum rn from
(select * from product a where company_id=? order by status) a
where rownum<=20)
where rn>10;
数据访问开销=索引IO+索引全部记录结果对应的表数据IO
采用rowid分页语法
优化原理是通过纯索引找出分页记录的ROWID,再通过ROWID回表返回数据,要求内层查询和排序字段全在索引里。
create index myindex on product(company_id,status);
select b.* from (
select * from (
select a.*,rownum rn from
(select rowid rid,status from product a where company_id=? order by status) a
where rownum<=20)
where rn>10) a, product b
where a.rid=b.rowid;
数据访问开销=索引IO+索引分页结果对应的表数据IO
实例:
一个公司产品有1000条记录,要分页取其中20个产品,假设访问公司索引需要50个IO,2条记录需要1个表数据IO。
那么按第一种ROWNUM分页写法,需要550(50+1000/2)个IO,按第二种ROWID分页写法,只需要60个IO(50+20/2);
2.2、只返回需要的字段
通过去除不必要的返回字段可以提高性能,例:
调整前:select * from product where company_id=?;
调整后:select id,name from product where company_id=?;
优点:
1、减少数据在网络上传输开销
2、减少服务器数据处理开销
3、减少客户端内存占用
4、字段变更时提前发现问题,减少程序BUG
5、如果访问的所有字段刚好在一个索引里面,则可以使用纯索引访问提高性能。
缺点:增加编码工作量
由于会增加一些编码工作量,所以一般需求通过开发规范来要求程序员这么做,否则等项目上线后再整改工作量更大。
如 果你的查询表中有大字段或内容较多的字段,如备注信息、文件内容等等,那在查询表时一定要注意这方面的问题,否则可能会带来严重的性能问题。如果表经常要 查询并且请求大内容字段的概率很低,我们可以采用分表处理,将一个大表分拆成两个一对一的关系表,将不常用的大内容字段放在一张单独的表中。如一张存储上 传文件的表:
T_FILE(ID,FILE_NAME,FILE_SIZE,FILE_TYPE,FILE_CONTENT)
我们可以分拆成两张一对一的关系表:
T_FILE(ID,FILE_NAME,FILE_SIZE,FILE_TYPE)
T_FILECONTENT(ID, FILE_CONTENT)
通过这种分拆,可以大大提少T_FILE表的单条记录及总大小,这样在查询T_FILE时性能会更好,当需要查询FILE_CONTENT字段内容时再访问T_FILECONTENT表。
篇2:面向程序员的数据库访问性能优化法则
3.1、batch DML
数据库访问框架一般都提供了批量提交的接口,jdbc支持batch的提交处理方法,当你一次性要往一个表中插入1000万条数据时,如果采用普通的executeUpdate处理,那么和服务器交互次数为1000万次,按每秒钟可以向数据库服务器提交10000次估算,要完成所有工作需要1000秒。如果采用批量提交模式,1000条提交一次,那么和服务器交互次数为1万次,交互次数大大减少。采用batch操作一般不会减少很多数据库服务器的物理IO,但是会大大减少客户端与服务端的交互次数,从而减少了多次发起的网络延时开销,同时也会降低数据库的CPU开销。
假设要向一个普通表插入1000万数据,每条记录大小为1K字节,表上没有任何索引,客户端与数据库服务器网络是100Mbps,以下是根据现在一般计算机能力估算的各种batch大小性能对比值:
单位:ms
No batch
Batch=10
Batch=100
Batch=1000
Batch=10000
服务器事务处理时间
0.1
0.1
0.1
0.1
0.1
服务器IO处理时间
0.02
0.2
2
20
200
网络交互发起时间
0.1
0.1
0.1
0.1
0.1
网络数据传输时间
0.01
0.1
1
10
100
小计
0.23
0.5
3.2
30.2
300.2
平均每条记录处理时间
0.23
0.05
0.032
0.0302
0.03002
从上可以看出,Insert操作加大Batch可以对性能提高近8倍性能,一般根据主键的Update或Delete操作也可能提高2-3倍性能,但不如Insert明显,因为Update及Delete操作可能有比较大的开销在物理IO访问。以上仅是理论计算值,实际情况需要根据具体环境测量。
3.2、In List
很多时候我们需要按一些ID查询数据库记录,我们可以采用一个ID一个请求发给数据库,如下所示:
for :var in ids[] do begin
select * from mytable where id=:var;
end;
我们也可以做一个小的优化,如下所示,用ID INLIST的这种方式写SQL:
select * from mytable where id in(:id1,id2,...,idn);
通过这样处理可以大大减少SQL请求的数量,从而提高性能。那如果有10000个ID,那是不是全部放在一条SQL里处理呢?答案肯定是否定的。首先大部份数据库都会有SQL长度和IN里个数的限制,如ORACLE的IN里就不允许超过1000个值,
另外当前数据库一般都是采用基于成本的优化规则,当IN数量达到一定值时有可能改变SQL执行计划,从索引访问变成全表访问,这将使性能急剧变化。随着SQL中IN的里面的值个数增加,SQL的执行计划会更复杂,占用的内存将会变大,这将会增加服务器CPU及内存成本。
评估在IN里面一次放多少个值还需要考虑应用服务器本地内存的开销,有并发访问时要计算本地数据使用周期内的并发上限,否则可能会导致内存溢出。
综合考虑,一般IN里面的值个数超过20个以后性能基本没什么太大变化,也特别说明不要超过100,超过后可能会引起执行计划的不稳定性及增加数据库CPU及内存成本,这个需要专业DBA评估。
3.3、设置Fetch Size
当我们采用select从数据库查询数据时,数据默认并不是一条一条返回给客户端的,也不是一次全部返回客户端的,而是根据客户端fetch_size参数处理,每次只返回fetch_size条记录,当客户端游标遍历到尾部时再从服务端取数据,直到最后全部传送完成。所以如果我们要从服务端一次取大量数据时,可以加大fetch_size,这样可以减少结果数据传输的交互次数及服务器数据准备时间,提高性能。
以下是jdbc测试的代码,采用本地数据库,表缓存在数据库CACHE中,因此没有网络连接及磁盘IO开销,客户端只遍历游标,不做任何处理,这样更能体现fetch参数的影响:
String vsql =“select * from t_employee”;
PreparedStatement pstmt = conn.prepareStatement(vsql,ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY);
pstmt.setFetchSize(1000);
ResultSet rs = pstmt.executeQuery(vsql);
int cnt = rs.getMetaData().getColumnCount();
Object o;
while (rs.next()) {
for (int i = 1; i <= cnt; i++) {
o = rs.getObject(i);
}
}
测试示例中的employee表有100000条记录,每条记录平均长度135字节
以下是测试结果,对每种fetchsize测试5次再取平均值:
fetchsize
elapse_time(s)
1
20.516
2
11.34
4
6.894
8
4.65
16
3.584
32
2.865
64
2.656
128
2.44
256
2.765
512
3.075
1024
2.862
2048
2.722
4096
2.681
8192
2.715
Oracle jdbc fetchsize默认值为10,由上测试可以看出fetchsize对性能影响还是比较大的,但是当fetchsize大于100时就基本上没有影响了。fetchsize并不会存在一个最优的固定值,因为整体性能与记录集大小及硬件平台有关。根据测试结果建议当一次性要取大量数据时这个值设置为100左右,不要小于40。注意,fetchsize不能设置太大,如果一次取出的数据大于JVM的内存会导致内存溢出,所以建议不要超过1000,太大了也没什么性能提高,反而可能会增加内存溢出的危险。
注:图中fetchsize在128以后会有一些小的波动,这并不是测试误差,而是由于resultset填充到具体对像时间不同的原因,由于resultset已经到本地内存里了,所以估计是由于CPU的L1,L2 Cache命中率变化造成,由于变化不大,所以笔者也未深入分析原因。
iBatis的SqlMapping配置文件可以对每个SQL语句指定fetchsize大小,如下所示:
3.4、使用存储过程
大型数据库一般都支持存储过程,合理的利用存储过程也可以提高系统性能。如你有一个业务需要将A表的数据做一些加工然后更新到B表中,但是又不可能一条SQL完成,这时你需要如下3步操作:
a:将A表数据全部取出到客户端;
b:计算出要更新的数据;
c:将计算结果更新到B表。
如果采用存储过程你可以将整个业务逻辑封装在存储过程里,然后在客户端直接调用存储过程处理,这样可以减少网络交互的成本。
当然,存储过程也并不是十全十美,存储过程有以下缺点:
a、不可移植性,每种数据库的内部编程语法都不太相同,当你的系统需要兼容多种数据库时最好不要用存储过程。
b、学习成本高,DBA一般都擅长写存储过程,但并不是每个程序员都能写好存储过程,除非你的团队有较多的开发人员熟悉写存储过程,否则后期系统维护会产生问题。
c、业务逻辑多处存在,采用存储过程后也就意味着你的系统有一些业务逻辑不是在应用程序里处理,这种架构会增加一些系统维护和调试成本。
d、存储过程和常用应用程序语言不一样,它支持的函数及语法有可能不能满足需求,有些逻辑就只能通过应用程序处理。
e、如果存储过程中有复杂运算的话,会增加一些数据库服务端的处理成本,对于集中式数据库可能会导致系统可扩展性问题。
f、为了提高性能,数据库会把存储过程代码编译成中间运行代码(类似于java的class文件),所以更像静态语言。当存储过程引用的对像(表、视图等等)结构改变后,存储过程需要重新编译才能生效,在24*7高并发应用场景,一般都是在线变更结构的,所以在变更的瞬间要同时编译存储过程,这可能会导致数据库瞬间压力上升引起故障(Oracle数据库就存在这样的问题)。
个人观点:普通业务逻辑尽量不要使用存储过程,定时性的ETL任务或报表统计函数可以根据团队资源情况采用存储过程处理。
3.5、优化业务逻辑
要通过优化业务逻辑来提高性能是比较困难的,这需要程序员对所访问的数据及业务流程非常清楚。
举一个案例:
某移动公司推出优惠套参,活动对像为VIP会员并且1,2,3月平均话费20元以上的客户。
那我们的检测逻辑为:
select avg(money) as avg_money from bill where phone_no='13988888888' and date between '01' and '201003';
select vip_flag from member where phone_no='13988888888';
if avg_money>20 and vip_flag=true then
begin
执行套参();
end;
如果我们修改业务逻辑为:
select avg(money) asavg_money from bill where phone_no='13988888888' and date between '201001' and '201003';
if avg_money>20 then
begin
select vip_flag from member where phone_no='13988888888';
if vip_flag=true then
begin
执行套参();
end;
end;
通过这样可以减少一些判断vip_flag的开销,平均话费20元以下的用户就不需要再检测是否VIP了。
如果程序员分析业务,VIP会员比例为1%,平均话费20元以上的用户比例为90%,那我们改成如下:
select vip_flag from member where phone_no='13988888888';
if vip_flag=true then
begin
select avg(money) as avg_money from bill where phone_no='13988888888' and date between '201001' and '201003';
if avg_money>20 then
begin
执行套参();
end;
end;
这样就只有1%的VIP会员才会做检测平均话费,最终大大减少了SQL的交互次数。
以上只是一个简单的示例,实际的业务总是比这复杂得多,所以一般只是高级程序员更容易做出优化的逻辑,但是我们需要有这样一种成本优化的意识。
3.6、使用ResultSet游标处理记录
现在大部分Java框架都是通过jdbc从数据库取出数据,然后装载到一个list里再处理,list里可能是业务Object,也可能是hashmap。
由于JVM内存一般都小于4G,所以不可能一次通过sql把大量数据装载到list里。为了完成功能,很多程序员喜欢采用分页的方法处理,如一次从数据库取1000条记录,通过多次循环搞定,保证不会引起JVM Out of memory问题。
以下是实现此功能的代码示例,t_employee表有10万条记录,设置分页大小为1000:
d1 = Calendar.getInstance().getTime();
vsql = “select count(*) cnt from t_employee”;
pstmt = conn.prepareStatement(vsql);
ResultSet rs = pstmt.executeQuery();
Integer cnt = 0;
while (rs.next()) {
cnt = rs.getInt(“cnt”);
}
Integer lastid=0;
Integer pagesize=1000;
System.out.println(“cnt:” + cnt);
String vsql = “select count(*) cnt from t_employee”;
PreparedStatement pstmt = conn.prepareStatement(vsql);
ResultSet rs = pstmt.executeQuery();
Integer cnt = 0;
while (rs.next()) {
cnt = rs.getInt(“cnt”);
}
Integer lastid = 0;
Integer pagesize = 1000;
System.out.println(“cnt:” + cnt);
for (int i = 0; i <= cnt / pagesize; i++) {
vsql = “select * from (select * from t_employee where id>? order by id) where rownum<=?”;
pstmt = conn.prepareStatement(vsql);
pstmt.setFetchSize(1000);
pstmt.setInt(1, lastid);
pstmt.setInt(2, pagesize);
rs = pstmt.executeQuery();
int col_cnt = rs.getMetaData().getColumnCount();
Object o;
while (rs.next()) {
for (int j = 1; j <= col_cnt; j++) {
o = rs.getObject(j);
}
lastid = rs.getInt(“id”);
}
rs.close();
pstmt.close();
}
以上代码实际执行时间为6.516秒
很多持久层框架为了尽量让程序员使用方便,封装了jdbc通过statement执行数据返回到resultset的细节,导致程序员会想采用分页的方式处理问题。实际上如果我们采用jdbc原始的resultset游标处理记录,在resultset循环读取的过程中处理记录,这样就可以一次从数据库取出所有记录。显著提高性能。
这里需要注意的是,采用resultset游标处理记录时,应该将游标的打开方式设置为FORWARD_READONLY模式(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY),否则会把结果缓存在JVM里,造成JVM Out of memory问题。
代码示例:
String vsql =“select * from t_employee”;
PreparedStatement pstmt = conn.prepareStatement(vsql,ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY);
pstmt.setFetchSize(100);
ResultSet rs = pstmt.executeQuery(vsql);
int col_cnt = rs.getMetaData().getColumnCount();
Object o;
while (rs.next()) {
for (int j = 1; j <= col_cnt; j++) {
o = rs.getObject(j);
}
}
调整后的代码实际执行时间为3.156秒
从测试结果可以看出性能提高了1倍多,如果采用分页模式数据库每次还需发生磁盘IO的话那性能可以提高更多。
iBatis等持久层框架考虑到会有这种需求,所以也有相应的解决方案,在iBatis里我们不能采用queryForList的方法,而应用该采用queryWithRowHandler加回调事件的方式处理,如下所示:
MyRowHandler myrh=newMyRowHandler();
sqlmap.queryWithRowHandler(“getAllEmployee”, myrh);
classMyRowHandlerimplementsRowHandler {
publicvoidhandleRow(Object o) {
//todo something
}
}
iBatis的queryWithRowHandler很好的封装了resultset遍历的事件处理,效果及性能与resultset遍历一样,也不会产生JVM内存溢出。
篇3:面向程序员的数据库访问性能优化法则
1.1、创建并使用正确的索引
数据库索引的原理非常简单,但在复杂的表中真正能正确使用索引的人很少,即使是专业的DBA也不一定能完全做到最优。
索引会大大增加表记录的DML(INSERT,UPDATE,DELETE)开销,正确的索引可以让性能提升100,1000倍以上,不合理的索引也可能会让性能下降100倍,因此在一个表中创建什么样的索引需要平衡各种业务需求。
索引常见问题:
索引有哪些种类?
常见的索引有B-TREE索引、位图索引、全文索引,位图索引一般用于数据仓库应用,全文索引由于使用较少,这里不深入介绍。B-TREE索引包括很多扩展类型,如组合索引、反向索引、函数索引等等,以下是B-TREE索引的简单介绍:
B-TREE索引也称为平衡树索引(Balance Tree),它是一种按字段排好序的树形目录结构,主要用于提升查询性能和唯一约束支持。B-TREE索引的内容包括根节点、分支节点、叶子节点。
叶子节点内容:索引字段内容+表记录ROWID
根节点,分支节点内容:当一个数据块中不能放下所有索引字段数据时,就会形成树形的根节点或分支节点,根节点与分支节点保存了索引树的顺序及各层级间的引用关系。
一个普通的BTREE索引结构示意图如下所示:
如果我们把一个表的内容认为是一本字典,那索引就相当于字典的目录,如下图所示:
图中是一个字典按部首+笔划数的目录,相当于给字典建了一个按部首+笔划的组合索引。
一个表中可以建多个索引,就如一本字典可以建多个目录一样(按拼音、笔划、部首等等)。
一个索引也可以由多个字段组成,称为组合索引,如上图就是一个按部首+笔划的组合目录。
SQL什么条件会使用索引?
当字段上建有索引时,通常以下情况会使用索引:
INDEX_COLUMN = ?
INDEX_COLUMN > ?
INDEX_COLUMN >= ?
INDEX_COLUMN < ?
INDEX_COLUMN <= ?
INDEX_COLUMN between ? and ?
INDEX_COLUMN in (?,?,...,?)
INDEX_COLUMN like ?||'%'(后导模糊查询)
T1. INDEX_COLUMN=T2. COLUMN1(两个表通过索引字段关联)
SQL什么条件不会使用索引?
查询条件
不能使用索引原因
INDEX_COLUMN ?
INDEX_COLUMN not in (?,?,...,?)
不等于操作不能使用索引
function(INDEX_COLUMN) = ?
INDEX_COLUMN + 1 = ?
INDEX_COLUMN || 'a' = ?
经过普通运算或函数运算后的索引字段不能使用索引
INDEX_COLUMN like '%'||?
INDEX_COLUMN like '%'||?||'%'
含前导模糊查询的Like语法不能使用索引
INDEX_COLUMN is null
B-TREE索引里不保存字段为NULL值记录,因此IS NULL不能使用索引
NUMBER_INDEX_COLUMN='12345'
CHAR_INDEX_COLUMN=12345
Oracle在做数值比较时需要将两边的数据转换成同一种数据类型,如果两边数据类型不同时会对字段值隐式转换,相当于加了一层函数处理,所以不能使用索引。
a.INDEX_COLUMN=a.COLUMN_1
给索引查询的值应是已知数据,不能是未知字段值。
注:
经过函数运算字段的字段要使用可以使用函数索引,这种需求建议与DBA沟通。
有时候我们会使用多个字段的组合索引,如果查询条件中第一个字段不能使用索引,那整个查询也不能使用索引
如:我们company表建了一个id+name的组合索引,以下SQL是不能使用索引的
Select * from company where name=?
Oracle9i后引入了一种index skip scan的索引方式来解决类似的问题,但是通过index skip scan提高性能的条件比较特殊,使用不好反而性能会更差。
我们一般在什么字段上建索引?
这是一个非常复杂的话题,需要对业务及数据充分分析后再能得出结果。主键及外键通常都要有索引,其它需要建索引的字段应满足以下条件:
1、字段出现在查询条件中,并且查询条件可以使用索引;
2、语句执行频率高,一天会有几千次以上;
3、通过字段条件可筛选的记录集很小,那数据筛选比例是多少才适合?
这个没有固定值,需要根据表数据量来评估,以下是经验公式,可用于快速评估:
小表(记录数小于10000行的表):筛选比例<10%;
大表:(筛选返回记录数)<(表总记录数*单条记录长度)/10000/16
单条记录长度≈字段平均内容长度之和+字段数*2
以下是一些字段是否需要建B-TREE索引的经验分类:
字段类型
常见字段名
需要建索引的字段
主键
ID,PK
外键
PRODUCT_ID,COMPANY_ID,MEMBER_ID,ORDER_ID,TRADE_ID,PAY_ID
有对像或身份标识意义字段
HASH_CODE,USERNAME,IDCARD_NO,EMAIL,TEL_NO,IM_NO
索引慎用字段,需要进行数据分布及使用场景详细评估
日期
GMT_CREATE,GMT_MODIFIED
年月
YEAR,MONTH
状态标志
PRODUCT_STATUS,ORDER_STATUS,IS_DELETE,VIP_FLAG
类型
ORDER_TYPE,IMAGE_TYPE,GENDER,CURRENCY_TYPE
区域
COUNTRY,PROVINCE,CITY
操作人员
CREATOR,AUDITOR
数值
LEVEL,AMOUNT,SCORE
长字符
ADDRESS,COMPANY_NAME,SUMMARY,SUBJECT
不适合建索引的字段
描述备注
DESCRIPTION,REMARK,MEMO,DETAIL
大字段
FILE_CONTENT,EMAIL_CONTENT
如何知道SQL是否使用了正确的索引?
简单SQL可以根据索引使用语法规则判断,复杂的SQL不好办,判断SQL的响应时间是一种策略,但是这会受到数据量、主机负载及缓存等因素的影响,有时数据全在缓存里,可能全表访问的时间比索引访问时间还少。要准确知道索引是否正确使用,需要到数据库中查看SQL真实的执行计划,这个话题比较复杂,详见SQL执行计划专题介绍。
索引对DML(INSERT,UPDATE,DELETE)附加的开销有多少?
这个没有固定的比例,与每个表记录的大小及索引字段大小密切相关,以下是一个普通表测试数据,仅供参考:
索引对于Insert性能降低56%
索引对于Update性能降低47%
索引对于Delete性能降低29%
因此对于写IO压力比较大的系统,表的索引需要仔细评估必要性,另外索引也会占用一定的存储空间。
1.2、只通过索引访问数据
有些时候,我们只是访问表中的几个字段,并且字段内容较少,我们可以为这几个字段单独建立一个组合索引,这样就可以直接只通过访问索引就能得到数据,一般索引占用的磁盘空间比表小很多,所以这种方式可以大大减少磁盘IO开销。
如:select id,name from company where type='2';
如果这个SQL经常使用,我们可以在type,id,name上创建组合索引
create index my_comb_index on company(type,id,name);
有了这个组合索引后,SQL就可以直接通过my_comb_index索引返回数据,不需要访问company表。
还是拿字典举例:有一个需求,需要查询一本汉语字典中所有汉字的个数,如果我们的字典没有目录索引,那我们只能从字典内容里一个一个字计数,最后返回结果。如果我们有一个拼音目录,那就可以只访问拼音目录的汉字进行计数。如果一本字典有1000页,拼音目录有20页,那我们的数据访问成本相当于全表访问的50分之一。
切记,性能优化是无止境的,当性能可以满足需求时即可,不要过度优化。在实际数据库中我们不可能把每个SQL请求的字段都建在索引里,所以这种只通过索引访问数据的方法一般只用于核心应用,也就是那种对核心表访问量最高且查询字段数据量很少的查询。
1.3、优化SQL执行计划
SQL执行计划是关系型数据库最核心的技术之一,它表示SQL执行时的数据访问算法。由于业务需求越来越复杂,表数据量也越来越大,程序员越来越懒惰,SQL也需要支持非常复杂的业务逻辑,但SQL的性能还需要提高,因此,优秀的关系型数据库除了需要支持复杂的SQL语法及更多函数外,还需要有一套优秀的算法库来提高SQL性能。
目前ORACLE有SQL执行计划的算法约300种,而且一直在增加,所以SQL执行计划是一个非常复杂的课题,一个普通DBA能掌握50种就很不错了,就算是资深DBA也不可能把每个执行计划的算法描述清楚。虽然有这么多种算法,但并不表示我们无法优化执行计划,因为我们常用的SQL执行计划算法也就十几个,如果一个程序员能把这十几个算法搞清楚,那就掌握了80%的SQL执行计划调优知识。
由于篇幅的原因,SQL执行计划需要专题介绍,在这里就不多说了。
篇4:面向程序员的数据库访问性能优化法则
4.1、使用绑定变量
绑定变量是指SQL中对变化的值采用变量参数的形式提交,而不是在SQL中直接拼写对应的值。
非绑定变量写法:Select * from employee where id=1234567
绑定变量写法:
Select * from employee where id=?
Preparestatement.setInt(1,1234567)
Java中Preparestatement就是为处理绑定变量提供的对像,绑定变量有以下优点:
1、防止SQL注入
2、提高SQL可读性
3、提高SQL解析性能,不使用绑定变更我们一般称为硬解析,使用绑定变量我们称为软解析。
第1和第2点很好理解,做编码的人应该都清楚,这里不详细说明。关于第3点,到底能提高多少性能呢,下面举一个例子说明:
假设有这个这样的一个数据库主机:
2个4核CPU
100块磁盘,每个磁盘支持IOPS为160
业务应用的SQL如下:
select * from table where pk=?
这个SQL平均4个IO(3个索引IO+1个数据IO)
IO缓存命中率75%(索引全在内存中,数据需要访问磁盘)
SQL硬解析CPU消耗:1ms(常用经验值)
SQL软解析CPU消耗:0.02ms(常用经验值)
假设CPU每核性能是线性增长,访问内存Cache中的IO时间忽略,要求计算系统对如上应用采用硬解析与采用软解析支持的每秒最大并发数:
是否使用绑定变量
CPU支持最大并发数
磁盘IO支持最大并发数
不使用
2*4*1000=8000
100*160=16000
使用
2*4*1000/0.02=400000
100*160=16000
从以上计算可以看出,不使用绑定变量的系统当并发达到8000时会在CPU上产生瓶颈,当使用绑定变量的系统当并行达到16000时会在磁盘IO上产生瓶颈。所以如果你的系统CPU有瓶颈时请先检查是否存在大量的硬解析操作。
使用绑定变量为何会提高SQL解析性能,这个需要从数据库SQL执行原理说明,一条SQL在Oracle数据库中的执行过程如下图所示:
当一条SQL发送给数据库服务器后,系统首先会将SQL字符串进行hash运算,得到hash值后再从服务器内存里的SQL缓存区中进行检索,如果有相同的SQL字符,并且确认是同一逻辑的SQL语句,则从共享池缓存中取出SQL对应的执行计划,根据执行计划读取数据并返回结果给客户端。
如果在共享池中未发现相同的SQL则根据SQL逻辑生成一条新的执行计划并保存在SQL缓存区中,然后根据执行计划读取数据并返回结果给客户端。
为了更快的检索SQL是否在缓存区中,首先进行的是SQL字符串hash值对比,如果未找到则认为没有缓存,如果存在再进行下一步的准确对比,所以要命中SQL缓存区应保证SQL字符是完全一致,中间有大小写或空格都会认为是不同的SQL。
如果我们不采用绑定变量,采用字符串拼接的模式生成SQL,那么每条SQL都会产生执行计划,这样会导致共享池耗尽,缓存命中率也很低。
一些不使用绑定变量的场景:
a、数据仓库应用,这种应用一般并发不高,但是每个SQL执行时间很长,SQL解析的时间相比SQL执行时间比较小,绑定变量对性能提高不明显。数据仓库一般都是内部分析应用,所以也不太会发生SQL注入的安全问题。
b、数据分布不均匀的特殊逻辑,如产品表,记录有1亿,有一产品状态字段,上面建有索引,有审核中,审核通过,审核未通过3种状态,其中审核通过9500万,审核中1万,审核不通过499万。
要做这样一个查询:
select count(*) from product where status=?
采用绑定变量的话,那么只会有一个执行计划,如果走索引访问,那么对于审核中查询很快,对审核通过和审核不通过会很慢;如果不走索引,那么对于审核中与审核通过和审核不通过时间基本一样;
对于这种情况应该不使用绑定变量,而直接采用字符拼接的方式生成SQL,这样可以为每个SQL生成不同的执行计划,如下所示。
select count(*) from product where status='approved'; //不使用索引
select count(*) from product where status='tbd'; //不使用索引
select count(*) from product where status='auditing';//使用索引
4.2、合理使用排序
Oracle的排序算法一直在优化,但是总体时间复杂度约等于nLog(n)。普通OLTP系统排序操作一般都是在内存里进行的,对于数据库来说是一种CPU的消耗,曾在PC机做过测试,单核普通CPU在1秒钟可以完成100万条记录的全内存排序操作,所以说由于现在CPU的性能增强,对于普通的几十条或上百条记录排序对系统的影响也不会很大。但是当你的记录集增加到上万条以上时,你需要注意是否一定要这么做了,大记录集排序不仅增加了CPU开销,而且可能会由于内存不足发生硬盘排序的现象,当发生硬盘排序时性能会急剧下降,这种需求需要与DBA沟通再决定,取决于你的需求和数据,所以只有你自己最清楚,而不要被别人说排序很慢就吓倒。
以下列出了可能会发生排序操作的SQL语法:
Order by
Group by
Distinct
Exists子查询
Not Exists子查询
In子查询
Not In子查询
Union(并集),Union All也是一种并集操作,但是不会发生排序,如果你确认两个数据集不需要执行去除重复数据操作,那请使用Union All代替Union。
Minus(差集)
Intersect(交集)
Create Index
Merge Join,这是一种两个表连接的内部算法,执行时会把两个表先排序好再连接,应用于两个大表连接的操作。如果你的两个表连接的条件都是等值运算,那可以采用Hash Join来提高性能,因为Hash Join使用Hash运算来代替排序的操作。具体原理及设置参考SQL执行计划优化专题。
4.3、减少比较操作
我们SQL的业务逻辑经常会包含一些比较操作,如a=b,a之类的操作,对于这些比较操作数据库都体现得很好,但是如果有以下操作,我们需要保持警惕:
Like模糊查询,如下所示:
a like ‘%abc%’
Like模糊查询对于数据库来说不是很擅长,特别是你需要模糊检查的记录有上万条以上时,性能比较糟糕,这种情况一般可以采用专用Search或者采用全文索引方案来提高性能。
不能使用索引定位的大量In List,如下所示:
a in (:1,:2,:3,…,:n)----n>20
如果这里的a字段不能通过索引比较,那数据库会将字段与in里面的每个值都进行比较运算,如果记录数有上万以上,会明显感觉到SQL的CPU开销加大,这个情况有两种解决方式:
a、将in列表里面的数据放入一张中间小表,采用两个表Hash Join关联的方式处理;
b、采用str2varList方法将字段串列表转换一个临时表处理,关于str2varList方法可以在网上直接查询,这里不详细介绍。
以上两种解决方案都需要与中间表Hash Join的方式才能提高性能,如果采用了Nested Loop的连接方式性能会更差。
如果发现我们的系统IO没问题但是CPU负载很高,就有可能是上面的原因,这种情况不太常见,如果遇到了最好能和DBA沟通并确认准确的原因。
4.4、大量复杂运算在客户端处理
什么是复杂运算,一般我认为是一秒钟CPU只能做10万次以内的运算。如含小数的对数及指数运算、三角函数、3DES及BASE64数据加密算法等等。
如果有大量这类函数运算,尽量放在客户端处理,一般CPU每秒中也只能处理1万-10万次这样的函数运算,放在数据库内不利于高并发处理。
篇5:面向程序员的数据库访问性能优化法则
5.1、客户端多进程并行访问
多进程并行访问是指在客户端创建多个进程(线程),每个进程建立一个与数据库的连接,然后同时向数据库提交访问请求。当数据库主机资源有空闲时,我们可以采用客户端多进程并行访问的方法来提高性能。如果数据库主机已经很忙时,采用多进程并行访问性能不会提高,反而可能会更慢。所以使用这种方式最好与DBA或系统管理员进行沟通后再决定是否采用。
例如:
我们有10000个产品ID,现在需要根据ID取出产品的详细信息,如果单线程访问,按每个IO要5ms计算,忽略主机CPU运算及网络传输时间,我们需要50s才能完成任务。如果采用5个并行访问,每个进程访问个ID,那么10s就有可能完成任务。
那是不是并行数越多越好呢,开1000个并行是否只要50ms就搞定,答案肯定是否定的,当并行数超过服务器主机资源的上限时性能就不会再提高,如果再增加反而会增加主机的进程间调度成本和进程冲突机率。
以下是一些如何设置并行数的基本建议:
如果瓶颈在服务器主机,但是主机还有空闲资源,那么最大并行数取主机CPU核数和主机提供数据服务的磁盘数两个参数中的最小值,同时要保证主机有资源做其它任务。
如果瓶颈在客户端处理,但是客户端还有空闲资源,那建议不要增加SQL的并行,而是用一个进程取回数据后在客户端起多个进程处理即可,进程数根据客户端CPU核数计算。
如果瓶颈在客户端网络,那建议做数据压缩或者增加多个客户端,采用map reduce的架构处理。
如果瓶颈在服务器网络,那需要增加服务器的网络带宽或者在服务端将数据压缩后再处理了。
5.2、数据库并行处理
数据库并行处理是指客户端一条SQL的请求,数据库内部自动分解成多个进程并行处理,如下图所示:
并不是所有的SQL都可以使用并行处理,一般只有对表或索引进行全部访问时才可以使用并行。数据库表默认是不打开并行访问,所以需要指定SQL并行的提示,如下所示:
select/*+parallel(a,4)*/* from employee;
并行的优点:
使用多进程处理,充分利用数据库主机资源(CPU,IO),提高性能。
并行的缺点:
1、单个会话占用大量资源,影响其它会话,所以只适合在主机负载低时期使用;
2、只能采用直接IO访问,不能利用缓存数据,所以执行前会触发将脏缓存数据写入磁盘操作。
注:
1、并行处理在OLTP类系统中慎用,使用不当会导致一个会话把主机资源全部占用,而正常事务得不到及时响应,所以一般只是用于数据仓库平台。
2、一般对于百万级记录以下的小表采用并行访问性能并不能提高,反而可能会让性能更差。
叶正盛(MKing)
-12-3
来自:blog.csdn.net/yzsind/article/details/6059209篇6:浅析SQL Server数据库的性能优化
在一个大型的数据库中,性能成为人们关注的焦点之一,如何让数据库高效有效的运行成为广大数据库管理人员和开发人员必须要考虑的问题,性能是一个应用或多个应用在相同的环境下运行时对效率的衡量。性能常用响应时间和工作效率来表示。响应时间是指完成一个任务花费的时间,可以从以下三方面来减少响应时间:
· 减少竞争和等待的次数,尤其是磁盘读写等待次数
· 利用更快的部件
· 减少利用资源所需的时间
绝大多数性能的获得来自于优秀的数据库设计、精确的查询分析和适当的索引。最好性能的获得能够通过确立优秀的数据库设计,在开发时学会使用SQL Server查询优化器来实现。
为了取得更好的数据库性能,我们就需要对数据库进行优化,减少系统资源的竞争,如对数据cache,过程cache,系统资源和CPU的竞争。
在SQL Server中,有如下优化层次:
·应用层——大部分性能的获得来自于对你的SQL应用中查询的优化,这必须是以好的数据库设计为基础的。
·数据库层——应用共享在数据库层中的资源,这些资源包括硬盘,事务日志和数据cache。
·服务器层——在服务器层有许多共享的资源,包括数据高速缓存,过程高速缓存,锁,CPU等。
·设备层——指的是存储数据的磁盘及其控制器,在这一层,你应尤其关注磁盘的I/O。
·网络层——指连接用户和SQL Server的网络。
·硬件层——指可利用的CPU。
·操作系统层——理想地,SQL Server是一台机器的唯一主要应用,它必须和操作系统以及其他sybase软件,如Backup Server或SQL Server Monitor共享处理器、内存以及其他资源。
在大多数情况下面,我们是对应用层进行优化,,因为对应用性能的优化是大家最乐于接受的功能,其结果能被观测及检验,查询的性能是SQL应用的整个性能的一个关键。
应用层上的问题包括以下内容:
·决策支持VS.和在线事务处理(OLTP)需要不同的性能策略
·事务设计能够减少并发,因为长的事务保持占用锁,也就减少了其他用户对相关数据的存取
·关联一致性对数据修改需要join操作
·支持Select操作的索引增加了修改数据的时间
·为了安全而设立的审计限制了性能
在应用层优化的选项包括:
·远程处理或复制处理能够把决策支持从OLTP机器中分离出来
·利用存储过程来减少编译时间和网络的利用
·利用最少量的锁去满足你的应用需要
数据库层的问题包括:
·建立备份和恢复方案
·在设备上分布存储数据
·审计操作影响性能;仅审计你所需的
·日常的维护活动将导致性能的降低和导致用户不能操作数据库表
在数据库层上优化选择包括:
·利用事务日志的阀值来自动转储事务日志防止其超出使用空间
·在数据段中用阀值来监视空间的使用
·利用分区来加速数据的装入
·对象的定位以避免硬盘的竞争
·把重要表和索引放入cache中,保证随时取得
服务器层的问题有:
·应用的类型——服务器是支持OLTP还是DSS,或者两者都支持
·所支持的用户数影响优化决策——随着用户数的增加,对资源的竞争会发生改变
·网络负荷
·当用户数和事务数达到一定的数量时复制服务器或其他分布式处理是一个解决的方法
服务器层的优化的选项包括:
·优化内存——一个关键的配置参数和其他方面的参数
·决策是客户端处理还是服务器端处理——有些处理能在客户端进行吗
·配置cache的大小和I/O的大小
·增加多个CPU
·为空闲时间排定批处理任务和生成报表
·工作负荷发生改变,重新配置特定参数
·决定是否可能把DSS移到另一个SQL服务器中设备层
设备层的问题包括:
·主设备、包含用户数据库的设备,用户数据设备,或数据库日志是否要镜像
·怎样在设备之间分布系统数据库、用户数据库和数据库日志
·为获得对堆表插入操作的高性能,是否有必要进行分区
设备层上优化的选项包括:
·用多个中等大小的设备及多个控制器可能比用少量的大设备有更好的I/O性能
·分布数据库,表和索引以在不同的设备上进行I/O装载
网络层
实际上,SQL Server的所有用户都是通过网络存取他们的数据,
网络层上的主要问题有:
·网络的流量
·网络的瓶颈
·网络的速度
网络层上优化的选项包括:
·配置包的大小,以使其与应用的需要相匹配
·配置子网
·分隔出繁忙的网络运用
·创建一个高容量的网络
·配置多个网络引擎
·更好地设计应用,限制所需的网络传输
硬件层
在硬件层上的问题包括
·CPU的效率
·磁盘的存取:控制器和磁盘
·磁盘备份
·内存的使用
在硬件层上优化的选项包括:
·增加CPU以适应工作负荷
·配置调度程序以提高CPU利用率
·遵循多处理器应用设计指导以减少竞争
·配置多个数据cache操作系统层
操作系统层的主要问题有:
·文件系统——是否被SQL Server独占使用
·内存管理——精确估算操作系统和其他程序的内存占用
·CPU的利用——整个系统共有多少处理器可用?有多少分配给SQL Server
在操作系统层优化的选项包括:
·网络接口
·在文件和原始分区之间选择
·增加内存
·把客户操作和批处理移到其他机器上
·SQL Server利用多个CPU
篇7:浅析SQL Server数据库的性能优化数据库
在一个大型的数据库中, 性能 成为人们关注的焦点之一,如何让数据库高效有效的运行成为广大数据库管理人员和 开发 人员必须要考虑的问题,性能是一个应用或多个应用在相同的环境下运行时对效率的衡量。性能常用响应时间和工作效率来表示。响应时间是指完成
在一个大型的数据库中,性能成为人们关注的焦点之一,如何让数据库高效有效的运行成为广大数据库管理人员和开发人员必须要考虑的问题。性能是一个应用或多个应用在相同的环境下运行时对效率的衡量。性能常用响应时间和工作效率来表示。响应时间是指完成一个任务花费的时间,可以从以下三方面来减少响应时间:
・ 减少竞争和等待的次数,尤其是磁盘读写等待次数
・ 利用更快的部件
・ 减少利用资源所需的时间
绝大多数性能的获得来自于优秀的数据库设计、精确的查询分析和适当的索引。最好性能的获得能够通过确立优秀的数据库设计,在开发时学会使用SQL Server查询优化器来实现。
为了取得更好的数据库性能,我们就需要对数据库进行优化,减少系统资源的竞争,如对数据cache,过程cache,系统资源和CPU的竞争。
在SQL Server中,有如下优化层次:
・应用层――大部分性能的获得来自于对你的SQL应用中查询的优化,这必须是以好的数据库设计为基础的。
・数据库层――应用共享在数据库层中的资源,这些资源包括硬盘,事务日志和数据cache。
・服务器层――在服务器层有许多共享的资源,包括数据高速缓存,过程高速缓存,锁,CPU等。
・设备层――指的是存储数据的磁盘及其控制器,在这一层,你应尤其关注磁盘的I/O。
・网络层――指连接用户和SQL Server的网络。
・硬件层――指可利用的CPU。
・操作系统层――理想地,SQL Server是一台机器的唯一主要应用,它必须和操作系统以及其他sybase软件,如Backup Server或SQL Server Monitor共享处理器、内存以及其他资源。
在大多数情况下面,我们是对应用层进行优化,,因为对应用性能的优化是大家最乐于接受的功能,其结果能被观测及检验,查询的性能是SQL应用的整个性能的一个关键。
应用层上的问题包括以下内容:
・决策支持VS.和在线事务处理(OLTP)需要不同的性能策略
・事务设计能够减少并发,因为长的事务保持占用锁,也就减少了其他用户对相关数据的存取
・关联一致性对数据修改需要join操作
・支持Select操作的索引增加了修改数据的时间
・为了安全而设立的审计限制了性能
在应用层优化的选项包括:
・远程处理或复制处理能够把决策支持从OLTP机器中分离出来
・利用存储过程来减少编译时间和网络的利用
・利用最少量的锁去满足你的应用需要
数据库层的问题包括:
・建立备份和恢复方案
・在设备上分布存储数据
・审计操作影响性能;仅审计你所需的
・日常的维护活动将导致性能的降低和导致用户不能操作数据库表
在数据库层上优化选择包括:
・利用事务日志的阀值来自动转储事务日志防止其超出使用空间
・在数据段中用阀值来监视空间的使用
・利用分区来加速数据的装入
・对象的定位以避免硬盘的竞争
・把重要表和索引放入cache中,保证随时取得
服务器层的问题有:
・应用的类型――服务器是支持OLTP还是DSS,或者两者都支持
・所支持的用户数影响优化决策――随着用户数的增加,对资源的竞争会发生改变
・网络负荷
・当用户数和事务数达到一定的数量时复制服务器或其他分布式处理是一个解决的方法
服务器层的优化的选项包括:
・优化内存――一个关键的配置参数和其他方面的参数
・决策是客户端处理还是服务器端处理――有些处理能在客户端进行吗
・配置cache的大小和I/O的大小
・增加多个CPU
・为空闲时间排定批处理任务和生成报表
・工作负荷发生改变,重新配置特定参数
・决定是否可能把DSS移到另一个SQL服务器中设备层
设备层的问题包括:
・主设备、包含用户数据库的设备,用户数据设备,或数据库日志是否要镜像
・怎样在设备之间分布系统数据库、用户数据库和数据库日志
・为获得对堆表插入操作的高性能,是否有必要进行分区
设备层上优化的选项包括:
・用多个中等大小的设备及多个控制器可能比用少量的大设备有更好的I/O性能
・分布数据库,表和索引以在不同的设备上进行I/O装载
网络层
实际上,SQL Server的所有用户都是通过网络存取他们的数据,
网络层上的主要问题有:
・网络的流量
・网络的瓶颈
・网络的速度
网络层上优化的选项包括:
・配置包的大小,以使其与应用的需要相匹配
・配置子网
・分隔出繁忙的网络运用
・创建一个高容量的网络
・配置多个网络引擎
・更好地设计应用,限制所需的网络传输
硬件层
在硬件层上的问题包括
・CPU的效率
・磁盘的存取:控制器和磁盘
・磁盘备份
・内存的使用
在硬件层上优化的选项包括:
・增加CPU以适应工作负荷
・配置调度程序以提高CPU利用率
・遵循多处理器应用设计指导以减少竞争
・配置多个数据cache操作系统层
操作系统层的主要问题有:
・文件系统――是否被SQL Server独占使用
・内存管理――精确估算操作系统和其他程序的内存占用
・CPU的利用――整个系统共有多少处理器可用?有多少分配给SQL Server
在操作系统层优化的选项包括:
・网络接口
・在文件和原始分区之间选择
・增加内存
・把客户操作和批处理移到其他机器上
・SQL Server利用多个CPU
(责任编辑:铭铭 mingming_ky@126.com TEL:(010)68476636)
原文转自:www.ltesting.net
篇8:突破瓶颈 数据库性能优化“路线图”
数据交互复杂度与频度的提升,导致了数据库在运维、迁移和规模扩展进程中的性能问题,作为一项确保企业IT基础部件健康运营的关键技术,数据库性能优化的实现路径和IT系统管理架构越来越密不可分。
南方某省级电信运营商的计费业务营账系统在上线运行后不久即出现性能问题。主要问题表现在最终用户的交互响应达不到预期,特别是在业务繁忙时段无法做出及时响应。从主机系统的角度观察,问题主要集中在系统的I/O(输入/输出)等待较大。而该营账系统由业务应用程序、甲骨文数据库、IBM AIX主机、IBM企业级存储服务器等部件构成,性能瓶颈的定位和优化过程均较为复杂。
数据库专家通过应用性能监测工具分析系统运行状况,在对主机和存储系统进行调优、并确保其能够满足现阶段生产系统的处理需求后,对甲骨文数据库的优化提出了针对性的建议。建议包括,为了应用系统扩容后处理压力的增大,对甲骨文数据库的性能参数进行修改;通过监测软件排查资源消耗最大的SQL语句的逻辑设计,将这些SQL语句的表结构与索引分别存储,建立合适的分区索引;通过监测软件对数据库和应用的数据分析,准确定位应用系统运行瓶颈,并做出相应的检查和调整。
这一典型案例浓缩了数据库性能优化过程中的几个关键步骤,及其在整体IT管理流程中的角色定位。在数据库成熟应用的时代,数据库的性能优化已经演变为一项相当严密的系统工程。作为企业IT基础设施的核心部件之一,数据库并不是孤立的系统,它与网络、操作系统、存储等硬件系统紧密相连,这种与其他IT部件的多重连接特性决定了数据库性能优化是一门综合技术。
在应用丛生、高度分布式的环境中,要总结出一套“放之四海皆准”的数据库性能优化方法论并不容易。但结合企业自身特色的性能优化流程却是有据可循的。在流程确立的过程之中,企业首先需要明确的问题就是,无论从什么样的角度切入,都要确保优化行为能够与IT系统的整体管理框架保持协调地联动,因为数据库的性能问题不仅仅局限在数据库内部。在大部分情况下,其优化行为都要围绕IT整体性能调优的思路展开。
路径全局谋划
古语云:“不谋全局者,不足谋一域。”说的是如果不从全局角度考虑问题,是无法获得局部智慧的。具体到数据库性能优化,通常包含针对应用、参数、存储、硬件、网络、操作系统的优化操作。有统计显示,对网络、硬件、操作系统、数据库参数进行优化所获得的性能提升,只占数据库系统性能提升的40%左右,其余60%的系统性能提升则来自于对应用程序的优化。作为金融、电信行业的资深数据库顾问,庄梁科技(北京)有限公司数据库专家牛新庄博士指出,数据库性能优化在很多时候都需要解决数据库以外的问题,这要求实践者具有完整的知识体系,是一项非常具有挑战性的工作。
“系统资源紧张是导致数据库性能问题的根本原因。”牛新庄博士说。针对常见的来自CPU、内存、磁盘I/O、网络的系统资源损耗,他总结了一套常规的问题流程。具体包含定位性能瓶颈、判断最消耗资源的应用或SQL,对逻辑资源的重新划分、、分析性能问题是否局限于数据库、追溯问题原因等步骤。
在阐述数据库性能优化的整体性时,海关数据库专家王翔强调,单点调优对数据库性能的提升意义不大。他指出,在针对常见的分布式数据库引擎的优化过程中,DBA(数据库管理员)的主要任务包括网络、架构、存储的调优和业务应用的优化,除此之外,还有通常被IT部门所忽视的用户体验的优化。“数据库性能优化存在很多程式化的内容,每一个的DBA都有自己解决问题的套路,而这些套路的共同点是从全局角度出发实施具体操作。”王翔说。
现阶段,用户反馈和运行监控是DBA发现数据库性能问题的主要来源。发现故障后,DBA需要用手动指令或专业的监控分析软件排查系统故障点,并确定合理的性能优化步骤。其基本的指导原则为,通过尽可能少的磁盘访问获取所需要的数据(常规的调优策略如图1所示)。数据库系统外的应用优化通常涉及源代码和SQL语句的调整。比较而言,源代码修改存在较高的时间成本,同时可获得的性能提升收益有限;由于应用程序对数据库的操作通常最终表现为SQL语句对数据库的操作,因此SQL语句的优化能够以提升SQL执行效率的方式实现数据库性能的提升。
图1:数据库性能优化常规策略
每个DBA眼中都有一条数据库最佳优化路径。而企业间IT应用的天然差异是导致这一结果的根本原因。同时,数据库性能优化方法还具有浓重的行业色彩。“银行的数据库应用以短交易为主,即主要涉及银行内部的固定数据处理流程,数据库优化主要以集成式优化操作为主;而税务行业的主营业务以长交易为主,一些审批流程需要在系统外部运转,其数据库故障的定位和优化将与短交易优化操作有所区别。”牛新庄说。
王翔在分析海关数据库应用特色时指出,海关数据库应用主要集中在甲骨文和SQL Server平台,数据处理以短交易为主,强调数据交换能力,但数据总体容量不如金融、电信等行业,同时数据交换以内部为主,不存在大量用户基础对数据库系统的访问。围绕这些特性,在实际的操作中,海关IT部门的数据库性能优化操作主要围绕基于快照、单双向复制的集成式优化展开。应用优化方面,主要涉及数据库参数的合理配置、数据库端缓冲调整,以及对频繁调用应用服务的打包处理。王翔介绍,中国海关专门成立了IT优化小组,负责制定和执行包括数据库在内的IT整体优化策略。
而在行业应用内部,不同系统对数据库性能的要求也不尽相同。以电信应用为例,某省级电信公司就从实际需要出发,将计费系统和销账系统分离,各自独立承载不同的数据处理任务。之所以进行这样的划分,是由于承载原始话单采集计费系统的特点表现在用户数少、数据库连接数少,数据存储量大,磁盘I/O高,但对响应时间的要求不高;而负责缴费的销账系统面对的是柜台营业员和电信用户,用户数量多,数据库连接数量大,但数据存储量和磁盘I/O都相比计费系统小得多,同时对系统响应时间要求高,要做到不超过3秒的时间响应。考虑到两种应用对数据库资源的需求存在很大差异,采用一个数据库会导致容量过大和管理不利,而I/O数据量过大时可直接降低响应时间。出于保证应用可靠性和系统安全的需要,该电信用户最终决定在设计时对两种功能的支持系统进行了明确划分。
谈到不同品牌的数据库优化流程是否存在差异的问题时,牛新庄和王翔两位数据库专家均表示,主流关系型数据库的优化基本遵循固定的流程。在具体的操作过程中,都是通过分析数据库对CPU、内存、磁盘I/O和网络的占用情况,与具体的应用相结合做出最终的性能瓶颈定位。但是,不同类型数据库的优化则会体现出明显的差异性。王翔指出,关系型数据库和XML数据库在数据库参数配置时就会涉及完全不同的技术细节。“关系型数据库的优化主要涉及索引的合理使用、I/O改造等内容,而XML数据库的磁盘I/O表现不同,数据存储以大字段为主,与应用的结合更为紧密。针对XML特性,DBA需要运用介于数据仓库和关系型数据库之间的数据库参数进行调整。”王翔说。
设计规避风险
和其他IT基础组件一样,数据库性能下降很大一部分的风险是能够在数据库的设计阶段予以规避的。因此,设计优化也就成为了数据库性能优化技术的源头和方向,
牛新庄指出,目前企业的数据库应用普遍表现出对设计阶段优化的忽视。根据多年的行业服务经验,他表示,企业对设计优化的不够重视主要体现在,工期紧张,开发时间短,以及系统匆忙上线后未经过充分优化和测试。“数据库逻辑结构的不合理、索引设计不合理,开发阶段的技术冲突无法调适,多种因素的累积作用导致了许多数据库系统上线后不久即出现性能故障”牛新庄说。
完整的数据库性能优化周期可以分为两个阶段,一是设计与开发阶段,主要负责对数据库逻辑和物理结构的优化设计,使其在满足具体业务需求的前提下,系统性能达到最佳,同时系统开销最小;二是数据库的运行阶段,其优化手段以数据库级、操作系统级、网络级为主。比较生命周期的调优成本与调优收益曲线,我们发现性能调优的成本随软件生命周期进程而增加,但调优收益却随软件生命周期进程而减少。由此可见,数据库上线之前的早期测试和调优工作不仅是日后数据库健康运维的基础,同时也可以有效避免那些应用后期不必要或需要付出高昂代价的优化操作。
为了减少因为数据库“被动”设计而导致的性能问题,王翔所在中国海关信息中心采用了DBA主动参与项目设计评审过程的方法,及早找出数据库的设计缺陷。项目协作方面,数据库专家还会与存储专家共同规划统一集中式存储架构,依据主干业务、其他业务等应用职能对数据库应用结构进行分割,并参与确立IT基础设施的备份、监控流程,力求将数据库的存储问题、物理布局等问题“消灭”在项目设计阶段。
术业有专攻
利器善事。数据库性能优化不能缺少有着丰富经验和严密知识体系的数据库专家,同样不能缺少完整的数据库性能保障框架和专业化的优化工具。伴随着关系型数据库三十余年的稳定发展,数据库性能优化已经成为商业IT管理软件供应商繁衍生息的乐土。老牌系统管理软件厂商BMC和CA都拥有数据库优化的产品工具;同时,这一领域还催生出很多以数据库优化为主营业务的软件公司,例如分布式数据库优化的领导者Quest Software、应用性能管理厂商Precise(被VERITAS公司以6亿美元的价格收购,并随VERITAS被赛门铁克连环收购,其i3产品系列并入赛门铁克旗下),以及提供图形化异构数据库管理工具厂商Embarcadero(相关产品及关键特性如附表所示)等。与此同时,数据库原厂商也向用户提供相关的优化工具。
“专业优化工具可以改变黑箱操作模式,为DBA呈现一张数据库实时运行状态的全息图。” Quest虹天软件(北京)有限公司高级经理田三稳说。据介绍,Quest Software的数据库优化工具Quest Central可支持甲骨文、DB2、SQL Server和MySQL平台, 能够快速诊断和解决多种数据库性能问题。通过直观的图形化用户界面,可以快速定位性能瓶颈,追溯问题根源,针对应用过程对最常见的SQL问题进行优化。Quest Central提供的自动化SQL优化机制,可以在不执行应用的前提下,通过代码扫描找出低效率查询并加以优化,消除SQL语句中的性能瓶颈。而待优化语句还会被自动重写为备份语句供DBA调整使用。
从甲骨文数据库优化起家的Quest Software,已经将其数据库性能优化产品扩展到多种关系型数据库平台。谈到以Quest为代表的专业优化软件的优势,田三稳表示,原厂商工具的局限性体现在缺乏跨平台的监控和诊断能力,而跨平台的数据库应用优化恰恰是企业的普遍需求。他坦言Quest Software正面临着来自原厂商工具的竞争。“随着甲骨文数据库的不断升级,它所附带的优化工具也开始提供一些与我们类似的功能,同时价格更低,但我们的优势是对跨平台数据库环境的透明支持,我们为客户提供了搭建集成化通用数据库性能优化平台的技术和方案”他说。他同时强调,与同类厂商相比,Quest Software的特色之处包括,具有亲和力的图形化诊断界面、独特的表空间重组技术、完善的底层专家知识库、自动化SQL优化以及对系统性能的实时诊断能力。
Quest Software拥有自己的数据库性能优化方法论,由监控、诊断和问题解决三个连贯的环节所构成,在兼容用户个性化管理需求的同时,可以为客户构建集中式、跨平台的数据库管理解决方案。目前,其优化工具已经在北京移动、上海移动、北京地税、北京电力、山西网通、海关总署、中国工商银行、东芝复印机等客户环境中得到部署。
一线数据库专家对专业优化软件持有自己的看法。牛新庄就指出,这些软件的主要功能是监控,能够定位问题却不能进行调整,当最后发现性能故障与应用或数据库设计有关后,还是需要DBA做出手工调整。在现阶段,市场上的专用软件仍无法替代数据库专家手中基于脚本的定制优化工具;海关的王翔则表示仍然习惯于脚本操作方式,大部分的数据库并没有安装图形化管理界面。“甲骨文的Web监控工具在实际的操作中还是不够实用,对于DBA来说,管理工具越轻量级约好。”王翔说。而很多DBA没有采用专用软件还有一个原因,就是在系统宕机时,这些工具是无法使用的,DBA必须通过脚本语句查看数据库内部状况。
针对DBA对手工操作和脚本方式的偏爱,田三稳表示,专用工具的很大一部分价值体现在对性能故障的预见和主动管理能力,以Quest Software工具为例,它既提供事先预警机制,还提供实时诊断、历史回放和性能参数的分析报告功能。“数据库高手可以凭经验或编写脚本来解决问题,但大部分中小企业的DBA并不具备这样的能力。Quest可以为这些企业提供一个功能齐全、使用方便的数据库监控管理平台,帮助他们建立起性能管理机制。”他说。他同时指出,一些企业具有非常高的IT审计要求,限制使用手工编写管理脚本或对数据库进行修改,这时专业工具的优势就显现出来。另外,在发现空间问题、空间重组和容量规划等数据库存储优化领域,Quest等工具也具备预防性维护和问题预测的能力。
经验、工具和全局观是做好数据库性能优化必不可少的三要素。今天的数据库性能优化不再是一个狭义的话题,当我们越来越深入其中,就会发现其覆盖了相当广阔的技术和管理领域。数据库应用的复杂性决定了DBA智慧和专用工具的协同作战将成为未来应用的方向,而作为一个垂直的优化流程,数据库性能优化将与新一代的IT管理框架实现更加透彻和更深层次的融合。
编看编想
这是个不断变化的话题,因为在IT应用快速进化的今天,数据库的职能和在IT系统架构中的角色定位在不停地变化着。这是我们仍会感觉这个话题如此鲜活而又充满探索可能的原因。
对每个DBA而言,这个话题所覆盖的庞大技术疆域都是极具诱人和挑战性的。在经验和专用工具之间,DBA们需要找到一条能够最快速发现问题和解决问题的路线图。必须承认,我们真的很难为这种处在不断变化中的技术应用绘制一幅“百战百胜”的路线图,但是可以针对可能出现的数据库故障建立相对固化的处理流程。所以,在DBA的脑海中,这幅路线图不一定有多么清晰或严谨,但它必须能够在你遇到问题时指引你该如何行动。
从某种意义上说,数据库性能优化是一项没有尽头的任务,因为用户对数据库性能的要求没有止境。在SOA时代,这一切会改变吗?很难预测重大架构变革所引发的具体技术的联动效应,但可以肯定的是,SOA框架下的数据库性能优化所面对的挑战比今天毫不逊色。王翔表示,SOA所强调服务自治性,是原有性能调优技术非常适用的;而在SOA的交互方面,应用对于服务编排和XML数据处理在交互过程中的重要性将进一步凸现,DBA需要根据应用“补补课”。
当数据库变身为数据服务,在成为独立服务的同时还要服务于众多的服务节点,这种超越以往的应用复杂性要求DBA刷新自己的知识体系、专用工具提供的管理功能更加精细化,同时也要求实践者在这个前所未有的开阔视野下,从崭新的战略全局观突破性能瓶颈。
数据库性能优化工具概览
篇9:SQL Server数据库性能优化数据库教程
server|数据|数据库|性能|优化
设计1个应用系统似乎并不难,但是要想使系统达到最优化的性能并不是一件容易的事,SQL Server数据库性能优化数据库教程
。在开发工具、数据库设计、应用程序的结构、查询设计、接口选择等方面有多种选择,这取决于特定的应用需求以及开发队伍的技能。本文以SQL Server为例,从后台数据库的角度讨论应用程序性能优化技巧,并且给出了一些有益的建议。1 数据库设计
要在良好的SQL Server方案中实现最优的性能,最关键的是要有1个很好的数据库设计方案。在实际工作中,许多SQL Server方案往往是由于数据库设计得不好导致性能很差。所以,要实现良好的数据库设计就必须考虑这些问题。
1.1 逻辑库规范化问题
一般来说,逻辑数据库设计会满足规范化的前3级标准:
1.第1规范:没有重复的组或多值的列。
2.第2规范:每个非关键字段必须依赖于主关键字,不能依赖于1个组合式主关键字的某些组成部分。
3.第3规范:1个非关键字段不能依赖于另1个非关键字段。
遵守这些规则的设计会产生较少的列和更多的表,因而也就减少了数据冗余,也减少了用于存储数据的页。但表关系也许需要通过复杂的合并来处理,这样会降低系统的性能。某种程度上的非规范化可以改善系统的性能,非规范化过程可以根据性能方面不同的考虑用多种不同的方法进行,但以下方法经实践验证往往能提高性能。
1.如果规范化设计产生了许多4路或更多路合并关系,就可以考虑在数据库实体(表)中加入重复属性(列)。
2.常用的计算字段(如总计、最大值等)可以考虑存储到数据库实体中。
比如某一个项目的计划管理系统中有计划表,其字段为:项目编号、年初计划、二次计划、调整计划、补列计划…,而计划总数(年初计划+二次计划+调整计划+补列计划)是用户经常需要在查询和报表中用到的,在表的记录量很大时,有必要把计划总数作为1个独立的字段加入到表中。这里可以采用触发器以在客户端保持数据的一致性。
3.重新定义实体以减少外部属性数据或行数据的开支。相应的非规范化类型是:
(1)把1个实体(表)分割成2个表(把所有的属性分成2组)。这样就把频繁被访问的数据同较少被访问的数据分开了。这种方法要求在每个表中复制首要关键字。这样产生的设计有利于并行处理,并将产生列数较少的表。
(2)把1个实体(表)分割成2个表(把所有的行分成2组)。这种方法适用于那些将包含大量数据的实体(表)。在应用中常要保留历史记录,但是历史记录很少用到。因此可以把频繁被访问的数据同较少被访问的历史数据分开。而且如果数据行是作为子集被逻辑工作组(部门、销售分区、地理区域等)访问的,那么这种方法也是很有好处的。
1.2 生成物理数据库
要想正确选择基本物理实现策略,必须懂得数据库访问格式和硬件资源的操作特点,主要是内存和磁盘子系统I/O。这是一个范围广泛的话题,但以下的准则可能会有所帮助。
1.与每个表列相关的数据类型应该反映数据所需的最小存储空间,特别是对于被索引的列更是如此。比如能使用smallint类型就不要用integer类型,这样索引字段可以被更快地读取,而且可以在1个数据页上放置更多的数据行,因而也就减少了I/O操作。
2.把1个表放在某个物理设备上,再通过SQL Server段把它的不分簇索引放在1个不同的物理设备上,这样能提高性能。尤其是系统采用了多个智能型磁盘控制器和数据分离技术的情况下,这样做的好处更加明显。
3.用SQL Server段把一个频繁使用的大表分割开,并放在2个单独的智能型磁盘控制器的数据库设备上,这样也可以提高性能。因为有多个磁头在查找,所以数据分离也能提高性能。
4.用SQL Server段把文本或图像列的数据存放在1个单独的物理设备上可以提高性能。1个专用的智能型的控制器能进一步提高性能。
2 与SQL Server相关的硬件系统
与SQL Server有关的硬件设计包括系统处理器、内存、磁盘子系统和网络,这4个部分基本上构成了硬件平台,Windows NT和SQL Server运行于其上。
2.1 系统处理器(CPU)
根据自己的具体需要确定CPU结构的过程就是估计在硬件平台上占用CPU的工作量的过程。从以往的经验看,CPU配置最少应是1个80586/100处理器。如果只有2~3个用户,这就足够了,但如果打算支持更多的用户和关键应用,推荐采用Pentium Pro或PⅡ级CPU。
2.2 内存(RAM)
为SQL Server方案确定合适的内存设置对于实现良好的性能是至关重要的。SQL Server用内存做过程缓存、数据和索引项缓存、静态服务器开支和设置开支。SQL Server最多能利用2GB虚拟内存,这也是最大的设置值。还有一点必须考虑的是Windows NT和它的所有相关的服务也要占用内存。
Windows NT为每个WIN32应用程序提供了4GB的虚拟地址空间。这个虚拟地址空间由Windows NT虚拟内存管理器(VMM)映射到物理内存上,在某些硬件平台上可以达到4GB。SQL Server应用程序只知道虚拟地址,所以不能直接访问物理内存,这个访问是由VMM控制的。Windows NT允许产生超出可用的物理内存的虚拟地址空间,这样当给SQL Server分配的虚拟内存多于可用的物理内存时,会降低SQL Server的性能。
这些地址空间是专门为SQL Server系统设置的,所以如果在同一硬件平台上还有其它软件(如文件和打印共享,应用程序服务等)在运行,那么应该考虑到它们也占用一部分内存。一般来说硬件平台至少要配置32MB的内存,其中,Windows NT至少要占用16MB。1个简单的法则是,给每一个并发的用户增加100KB的内存。例如,如果有100个并发的用户,则至少需要32MB+100用户*100KB=42MB内存,实际的使用数量还需要根据运行的实际情况调整。可以说,提高内存是提高系统性能的最经济的途径。
2.3 磁盘子系统
设计1个好的磁盘I/O系统是实现良好的SQL Server方案的一个很重要的方面。这里讨论的磁盘子系统至少有1个磁盘控制设备和1个或多个硬盘单元,还有对磁盘设置和文件系统的考虑。智能型SCSI-2磁盘控制器或磁盘组控制器是不错的选择,其特点如下:
(1)控制器高速缓存。
(2)总线主板上有处理器,可以减少对系统CPU的中断。
(3)异步读写支持。
(4)32位RAID支持。
(5)快速SCSI―2驱动。
(6)超前读高速缓存(至少1个磁道)。
3 检索策略
在精心选择了硬件平台,又实现了1个良好的数据库方案,并且具备了用户需求和应用方面的知识后,现在应该设计查询和索引了。有2个方面对于在SQL Server上取得良好的查询和索引性能是十分重要的,第1是根据SQL Server优化器方面的知识生成查询和索引;第2是利用SQL Server的性能特点,加强数据访问操作,
3.1 SQL Server优化器
Microsoft SQL Server数据库内核用1个基于费用的查询优化器自动优化向SQL提交的数据查询操作。数据操作查询是指支持SQL关键字WHERE或HAVING的查询,如SELECT、DELETE和UPDATE。基于费用的查询优化器根据统计信息产生子句的费用估算。
了解优化器数据处理过程的简单方法是检测SHOWPLAN命令的输出结果。如果用基于字符的工具(例如isql),可以通过键入SHOW SHOWPLAN ON来得到SHOWPLAN命令的输出。如果使用图形化查询,比如SQL Enterprise Manager中的查询工具或isql/w,可以设定配置选项来提供这一信息。
SQL Server的优化通过3个阶段完成:查询分析、索引选择、合并选择。
1.查询分析
在查询分析阶段,SQL Server优化器查看每一个由正规查询树代表的子句,并判断它是否能被优化。SQL Server一般会尽量优化那些限制扫描的子句。例如,搜索和/或合并子句。但是不是所有合法的SQL语法都可以分成可优化的子句,如含有SQL不等关系符“”的子句。因为“”是1个排斥性的操作符,而不是1个包括性的操作符,所在扫描整个表之前无法确定子句的选择范围会有多大。当1个关系型查询中含有不可优化的子句时,执行计划用表扫描来访问查询的这个部分,对于查询树中可优化的SQL Server子句,则由优化器执行索引选择。
2.索引选择
对于每个可优化的子句,优化器都查看数据库系统表,以确定是否有相关的索引能用于访问数据。只有当索引中的列的1个前缀与查询子句中的列完全匹配时,这个索引才被认为是有用的。因为索引是根据列的顺序构造的,所以要求匹配是精确的匹配。对于分簇索引,原来的数据也是根据索引列顺序排序的。想用索引的次要列访问数据,就像想在电话本中查找所有姓为某个姓氏的条目一样,排序基本上没有什么用,因为你还是得查看每一行以确定它是否符合条件。如果1个子句有可用的索引,那么优化器就会为它确定选择性。
所以在设计过程中,要根据查询设计准则仔细检查所有的查询,以查询的优化特点为基础设计索引。
(1)比较窄的索引具有比较高的效率。对于比较窄的索引来说,每页上能存放较多的索引行,而且索引的级别也较少。所以,缓存中能放置更多的索引页,这样也减少了I/O操作。
(2)SQL Server优化器能分析大量的索引和合并可能性。所以与较少的宽索引相比,较多的窄索引能向优化器提供更多的选择。但是不要保留不必要的索引,因为它们将增加存储和维护的开支。对于复合索引、组合索引或多列索引,SQL Server优化器只保留最重要的列的分布统计信息,这样,索引的第1列应该有很大的选择性。
(3)表上的索引过多会影响UPDATE、INSERT和DELETE的性能,因为所有的索引都必须做相应的调整。另外,所有的分页操作都被记录在日志中,这也会增加I/O操作。
(4)对1个经常被更新的列建立索引,会严重影响性能。
(5)由于存储开支和I/O操作方面的原因,较小的自组索引比较大的索引性能更好一些。但它的缺点是要维护自组的列。
(6)尽量分析出每一个重要查询的使用频度,这样可以找出使用最多的索引,然后可以先对这些索引进行适当的优化。
(7)查询中的WHERE子句中的任何列都很可能是个索引列,因为优化器重点处理这个子句。
(8)对小于1个范围的小型表进行索引是不划算的,因为对于小表来说表扫描往往更快而且费用低。
(9)与“ORDER BY”或“GROUP BY”一起使用的列一般适于做分族索引。如果“ORDER BY”命令中用到的列上有分簇索引,那么就不会再生成1个工作表了,因为行已经排序了。“GROUP BY”命令则一定产生1个工作表。
(10)分簇索引不应该构造在经常变化的列上,因为这会引起整行的移动。在实现大型交易处理系统时,尤其要注意这一点,因为这些系统中数据往往是频繁变化的。
3.合并选择
当索引选择结束,并且所有的子句都有了一个基于它们的访问计划的处理费用时,优化器开始执行合并选择。合并选择被用来找出一个用于合并子句访问计划的有效顺序。为了做到这一点,优化器比较子句的不同排序,然后选出从物理磁盘I/O的角度看处理费用最低的合并计划。因为子句组合的数量会随着查询的复杂度极快地增长,SQL Server查询优化器使用树剪枝技术来尽量减少这些比较所带来的开支。当这个合并选择阶段结束时,SQL Server查询优化器已经生成了1个基于费用的查询执行计划,这个计划充分利用了可用的索引,并以最小的系统开支和良好的执行性能访问原来的数据。
3.2 高效的查询选择
从以上查询优化的3个阶段不难看出,设计出物理I/O和逻辑I/O最少的方案并掌握好处理器时间和I/O时间的平衡,是高效查询设计的主要目标。也就是说,希望设计出这样的查询:充分利用索引、磁盘读写最少、最高效地利用了内存和CPU资源。
以下建议是从SQL Server优化器的优化策略中总结出来的,对于设计高效的查询是很有帮助的。
1.如果有独特的索引,那么带有“=”操作符的WHERE子句性能最好,其次是封闭的区间(范围),再其次是开放的区间。
2.从数据库访问的角度看,含有不连续连接词(OR和IN)的WHERE子句一般来说性能不会太好。所以,优化器可能会采用R策略,这种策略会生成1个工作表,其中含有每个可能匹配的执行的标识符,优化器把这些行标志符(页号和行号)看做是指向1个表中匹配的行的“动态索引”。优化器只需扫描工作表,取出每一个行标志符,再从数据表中取得相应的行,所以R策略的代价是生成工作表。
3.包含NOT、、或! =的WHERE子句对于优化器的索引选择来说没有什么用处。因为这样的子句是排斥性的,而不是包括性的,所以在扫描整个原来数据表之前无法确定子句的选择性。
4.限制数据转换和串操作,优化器一般不会根据WHERE子句中的表达式和数据转换式生成索引选择。例如:
paycheck * 12>36000 or substring(lastname,1,1)=“L”
如果该表建立了针对paycheck和lastname的索引,就不能利用索引进行优化,可以改写上面的条件表达式为:
paycheck<36000/12 or lastname like “L%”
5.WHERE子句中的本地变量被认为是不被优化器知道和考虑的,例外的情况是定义为储备过程输入参数的变量。
6.如果没有包含合并子句的索引,那么优化器构造1个工作表以存放合并中最小的表中的行。然后再在这个表上构造1个分簇索引以完成一个高效的合并。这种作法的代价是工作表的生成和随后的分族索引的生成,这个过程叫REFORMATTING。 所以应该注意RAM中或磁盘上的数据库tempdb的大小(除了SELECT INTO语句)。另外,如果这些类型的操作是很常见的,那么把tempdb放在RAM中对于提高性能是很有好处的。
4 性能优化的其他考虑
上面列出了影响SQL Server的一些主要因素,实际上远不止这些。操作系统的影响也很大,在Windows NT下,文件系统的选择、网络协议、开启的服务、SQL Server的优先级等选项也不同程度上影响了SQL Server的性能。
影响性能的因素是如此的多,而应用又各不相同,找出1个通用的优化方案是不现实的,在系统开发和维护的过程中必须针对运行的情况,不断加以调整。事实上,绝大部分的优化和调整工作是在与客户端独立的服务器上进行的,因此也是现实可行的。
【面向程序员的数据库访问性能优化法则】相关文章:






文档为doc格式