oracle数据库:开发成功的Oracle应用_笔记5
1.3开发数据库应用的正确(和不正确)方法 oracle数据库:开发成功的Oracle应用【笔记1】http://www.52ij.com/jishu/5127.html oracle数据库:开发成功的Oracle应用【笔记2】http://www.52ij.com/jishu/5128.html oracle数据库:开发成功的Oracle应用【笔记3】http://www.52ij.com/jishu/5129.html Oracle:开发成功的Oracle应用_Select...For update http://www.52ij.com/jishu/5131.html
1.3.1了解oracle体系结构
要把应用从一个数据库真正移植到另一个数据库,这绝对是一项大工程。而大多数应用通常都是根据“最小移植”得来的。
在某种特殊的情况下,SQL Server体系结构和SQL Server的使用方法会影响Oracle实现。这种“移植”的目标是扩展应用,但“移植”应用的开发人员一方面想达到这个目的,另一方面又想尽量少出力。所以,开发人员往往保持客户和数据库层的体系结构基本不变。这种决定最糟糕的两个后果是:
Oracle中采用SQL Server同样的数据库连接体系结构。
开发人员在SQL中使用字面量(而不是绑定变量)。
这两个结果导致系统无法支持所需的用户负载(数据库服务器的可用内存会耗尽),应用的性能也极差。
1、在Oracle中使用一个连接
目前SQL Server中有一种很普遍的做法,就是对想要执行的每条并发语句都打开一个数据库连接。如果想执行5个查询,可能就会在SQL Server中看到5个连接。在Oracle中,不论你想执行5个查询还是500个查询,都希望最多打开一个连接。所以,SQL Server中常用的做法在Oracle中却不提倡;你可能并不想维护多个数据库连接。
针对这个问题,可能的解决方案有3种,无论哪一种解决方案都需要做大量工作。具体如下:
1重建应用,充分考虑到这样一个事实:应用是在Oracle上运行,而不是在另外某个数据库上;另外生成一个页面只使用一个连接,而不是5-15个连接。这是从根本上解决这个问题的唯一方法。
2升级操作系统,使用Windows Data Center版本中更大的内存模型
3把数据库从Windows系列操作系统移植到另外某个使用多进程的操作系统,以便数据库使用所安装的全部RAM。在32位Windows平台上,PGA和SGA域总共最多有2GB RAM,因为它们是由单进程分配的。在32位多进程平台上,SGA和PGA每个进程最多为2GB RAM,比在32位Windows平台上多多了。
2、使用绑定变量
“不使用绑定变量”是导致性能问题的一个主要原因,也是阻碍可扩展性的一个重要因素,更不用说,它也极大地提高了安全风险。Oracle共享池(shared pool)是一个非常重要的共享内存结构,在大多数情况下,它的操作方式是由开发人员使用绑定变量断定的。如果确实想让Oracle缓慢地运行,甚至几近停顿,只要根本不使用绑定变量就可以办到。
select * from emp where empno=123;
select * from emp where empno= :empno;
第二个查询使用了一个绑定变量:empno,变量值在查询执行时提供。这个查询只编译一次,随后会把查询计划存储在一个共享池(库缓存)中,以便以后获取和重用这个查询计划。
从前面的描述应该能清楚地看到,与重用已解析的查询计划(称为软解析,soft parse)相比,解析包含有硬编码变量的语句(称为硬解析,hard parse)需要的时间更长,而且要消耗更多的资源。硬解析会减少系统能支持的用户数,但程序如何不太明显。这部分取决于多耗费了多少资源,但更重要的因素是库缓存所用的闩定机制。硬解析一个查询时,数据库会更长时间地占用一种低级串行化设备,这称为闩,这些闩能保护Oracle共享内存中的数据结构不会同时被两个进程修改,而且如果有人正在修改数据结构,则不允许另外的人再来读取。对这些数据结构加闩的时间越长、越频繁,排队等待闩的进程就越多,等待队列也越长。
数据库中只要有一个应用表现不佳,就会严重地影响所有其他应用的性能。如果只有一个小应用没有使用绑定变量,那么即使其他应用原本设计得很好,能适当地将已解析的SQL放在共享池中以备重用,但因为这个小应用的存在,过一段时间就会从共享池中删除已存储的SQL。这就使得这些设计得当的应用也必须再次硬解析SQL。
测试:
sys@ORCL>create table t(x int);
Table created.
sys@ORCL>create or replace procedure proc1
2 as
3 begin
4 for i in 1..10000
5 loop
6 execute immediate
7 'insert into t values(:x)' using i;
8 end loop;
9 end;
10 /
Procedure created.
sys@ORCL>l
1 create or replace procedure proc2
2 as
3 begin
4 for i in 1..10000
5 loop
6 execute immediate
7 'insert into t values('||i||')' ;
8 end loop;
9* end;
sys@ORCL>/
Procedure created.
sys@ORCL>exec runstats_pkg.rs_start
PL/SQL procedure successfully completed.
sys@ORCL>exec proc1
PL/SQL procedure successfully completed.
sys@ORCL>exec runstats_pkg.rs_middle
PL/SQL procedure successfully completed.
sys@ORCL>exec proc2
PL/SQL procedure successfully completed.
sys@ORCL>exec runstats_pkg.rs_stop(10000)
Run1 ran in150cpu hsecs
Run2 ran in829cpu hsecs
run 1 ran in18.09% of the time
Name Run1 Run2 Diff
STAT...calls to kcmgcs 57 10,058 10,001
STAT...parse count (hard) 4 10,011 10,007
STAT...parse count (total) 5 10,027 10,022
STAT...session logical reads 10,403 20,428 10,025
STAT...consistent gets from ca 36 10,065 10,029
STAT...consistent gets 55 10,134 10,079
STAT...consistent gets from ca 55 10,134 10,079
STAT...sql area evicted 1 10,419 10,418
LATCH.enqueue hash chains 685 21,001 20,316
LATCH.cache buffers chains 52,054 74,662 22,608
STAT...recursive calls 10,044 40,167 30,123
LATCH.shared pool simulator 36 41,064 41,028
STAT...session uga memory 65,488 0 -65,488
STAT...session pga memory max 0 65,536 65,536
STAT...session pga memory 0 65,536 65,536
LATCH.row cache objects 642 92,028 91,386
STAT...session uga memory max 157,152 31,848 -125,304
LATCH.shared pool 20,524 453,791 433,267
STAT...logical read bytes from 85,221,376 167,346,176 82,124,800
Run1 latches total versus runs -- difference and pct
Run1 Run2 Diff Pct
78,599 689,525 610,926 11.40%
PL/SQL procedure successfully completed.
sys@ORCL>
本文来源 我爱IT技术网 http://www.52ij.com/jishu/5132.html 转载请保留链接。
- 评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
-
