Oracle设计开发指南
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
知识库Oracle设计开发指南
版本历史
目录
1.引言 (6)
1.1目的 (6)
1.2范围、约束及假设 (6)
1.3定义、首字母缩写词和缩略语 (6)
1.4阅读对象 (6)
1.5参考资料 (6)
1.6文档概述 (6)
2.数据库设计 (6)
2.1逻辑设计 (6)
2.1.1表设计 (6)
2.1.2范式和冗余 (7)
2.1.3索引设计 (7)
2.1.4聚簇设计 (8)
2.1.5视图设计 (8)
2.2物理设计 (9)
2.2.1内存参数设计 (9)
2.2.2表容量估算 (9)
2.2.3索引容量估算 (9)
2.2.4存储参数设计 (9)
2.2.5表空间设计 (9)
2.2.6数据文件设计 (9)
2.2.7重做日志文件设计 (9)
2.2.8回滚段设计 (9)
2.3命名规范 (9)
2.3.1一般性命名规范 (9)
2.3.2对象命名规范 (9)
3.SQL优化 (11)
3.1SQL执行过程 (11)
3.1.1解析SQL (11)
3.1.2执行SQL (11)
3.1.3显示结果集 (11)
3.2SQL优化器 (12)
3.2.1优化器的优化方式 (12)
3.3SQL优化过程 (12)
3.3.1确定具有高影响力的SQL语句 (12)
3.3.2抽取和解释SQL语句 (13)
3.3.3调整SQL语句 (13)
3.4SQL调整工具 (13)
3.4.1Oracle AutoTrace (13)
3.4.2TKPROF工具 (15)
3.4.3STATSPACK工具 (16)
3.5O RACLE SQL优化方法 (32)
3.5.1选用适合的ORACLE优化器 (32)
3.5.2访问Table的方式 (32)
3.5.3共享SQL语句 (33)
3.5.4选择最有效率的表名顺序 (34)
3.5.5WHERE子句中的连接顺序 (34)
3.5.6SELECT子句中避免使用... * ... . (35)
3.5.7减少访问数据库的次数 (35)
3.5.8使用DECODE函数来减少处理时间 (36)
3.5.9删除重复记录 (37)
3.5.10用TRUNCATE替代DELETE (37)
3.5.11HWM对数据库性能的影响 (37)
3.5.12尽量多使用COMMIT (38)
3.5.13用Where子句替换HAVING子句 (38)
3.5.14减少对表的查询 (39)
3.5.15使用表的别名(Alias) (39)
3.5.16用EXISTS替代IN (39)
3.5.17用NOT EXISTS替代NOT IN (40)
3.5.18用表连接替换EXISTS (40)
3.5.19用EXISTS替换DISTINCT (41)
3.5.20识别‟低效执行‟的SQL语句 (41)
3.5.21提高insert、update速度 (41)
3.6调整查询 (42)
3.6.1查询调整方法 (42)
3.6.2子查询调整方法 (42)
3.6.3使用Oracle并行查询发挥多CPU的威力 (43)
3.7排序优化 (44)
3.7.1Oracle SQL排序原理 (44)
3.7.2需要进行排序的操作 (45)
3.7.3排序性能诊断 (45)
3.7.4监控临时表空间的使用情况 (45)
3.8调整表联接 (46)
3.8.1表联接类型 (46)
3.8.2Oracle优化器联接原理 (49)
3.8.3联接优化 (53)
3.9调整DML语句 (53)
3.9.1Oracle存储参数和DML性能 (53)
3.9.2空闲列表管理和DML性能 (55)
3.9.3索引和DML性能 (56)
3.10用索引调整SQL (56)
3.10.1Oracle索引概述 (56)
3.10.2索引不被使用的场景 (58)
3.10.3索引使用方法 (58)
3.11分页优化技术 (59)
3.11.1分页查询概述 (59)
3.11.2单表分页查询 (59)
3.11.3联接分页查询 (60)
3.11.4UNION ALL分页查询 (61)
3.11.5使用ROW_NUMBER函数分页 (64)
Oracle设计开发指南错误!未指定书签。
错误!未指定书签。
3、引言
a)目的
b)范围、约束及假设
c)定义、首字母缩写词和缩略语
d)阅读对象
e)参考资料
f)文档概述
4、数据库设计
a)逻辑设计
i.表设计
1、选择合适的数据类型与长度
选择最合适的数据类型,避免数据类型转换;确定好字段的长度,避免浪费存储空间;若在创建字段的时候,不能够确认字段长度的话,则最好采用变长的数据类型。
禁止使用LONG和LONG RAW类
型,应使用BLOB或CLOB类型。
2、确定表需要采用的完整性约束与默认值。
在建立表之前,需要确定列的主键约束、外键约束、非空约束、唯一性约束和CHECK约束;需要确认列的默认值。
3、在设计大表时,把允许NULL的列放在表的后面。
在数据库存储的时候,若字段为NULL,则这个值根本没有存储。
把允许NULL的字段放在表的末尾,当数据库比较大或者空字段比较多的话,则可以大大的减少数据库的存储空间。
Oracle表列建立好之后,除非重新删除再建立,否则无法调整列的顺序。
因此在创建表之前,要对列、以及是否为空有一个明确的定义。
只有如此,才能够合理安排列的顺序。
4、确定表需要采用的类型。
对于数据量比较大的表(Oracle建议:单个表大小超过2G),根据表数据的属性进行分区,以得到较好的性能。
如果表按某些字段进行增长,则采用按字段值范围进行范围分区。
如果表按某个字段的几个关键值进行分布,则采用列表分区。
对于静态表,则采用Hash分区或列表分区。
在范围分区中,如果数据按某关键字段均衡分布,则采用子分区的复合分区方法。
表中数据多数情况下按主键列进行查询且更新不频繁应使用索引表或聚簇表,其他情况下使用普通的堆表。
5、每个表在创建时候,必须指定所在的表空间,不要采用默认表空间以防止表建立在系统表空间上导致性能问题。
对于事务比较繁忙的数据表,必须存放在该表的专用表空间中。
表的数据和索引应存放在不同的表空间中。
大二进制数据列存储于独立表空间中。
6、每个表均创建类型为Sequence的主键字段。
为每个表增加如下字段:LAST_UPDATE_DATE、LAST_UPDATE_USER_SEQ、CREATE_DATE、CREATE_USER_SEQ。
为每个业务数据表增加以下字段:COMPANY_SEQ (租户序列号)。
为每个数据表增加删除标记字段。
为业务数据表增加5-8个保留字段。
ii.范式和冗余
如果没有性能上的原因,应该使用关系数据库理论,达到较高的范式,避免数据冗余。
如果在数据量上与性能上有一定要求,并且表的更新率较低,查询率较高,考虑到实现的方便性可以有适当的数据冗余。
iii.索引设计
iv.聚簇设计
Oracle支持两种类型的聚簇:索引聚簇和哈希聚簇
1.使用索引聚簇
2.使用哈希聚簇
v.视图设计
b)物理设计
i.内存参数设计
ii.表容量估算
iii.索引容量估算
iv.存储参数设计
v.表空间设计
vi.数据文件设计
vii.重做日志文件设计
viii.回滚段设计
c)命名规范
i.一般性命名规范
ii.对象命名规范
a)SQL执行过程
i.解析SQL
ii.执行SQL
iii.显示结果集
这一步骤将对字段数据执行所有必要的排序、转换和重新格式化。
Oracle在执行一个SQL之前,首先要分析一下语句的执行计划,然后再按执行计划去执行。
分析
语句的执行计划的工作是由优化器(Optimizer)来完成的。
不同的情况,一条SQL可能有多种执行计划,但在某一时点,一定只有一种执行计划是最优的,花费时间是最少的。
i.优化器的优化方式
Oracle的优化器共有两种的优化方式,即基于规则的优化方式(Rule-Based Optimization,简称
为RBO)和基于成本的优化方式(Cost-Based Optimization,简称为CBO)。
1、RBO方式:优化器在分析SQL语句时,所遵循的是Oracle内部预定的一些规则。
比如我们常
见的,当一个where子句中的一列有索引时,优化器会选择按索引扫描。
2、CBO方式:依词义可知,它是看SQL语句的代价(Cost),这里的代价主要指CPU和内存。
优化
器在判断是否用这种方式时,主要参照的是表及索引的统计信息。
统计信息给出表的大小、有多少行、每行的长度等信息。
这些统计信息起初在库内是没有的,是你在做analyze后才出现的,很多的时侯过期统计信息会令优化器做出一个错误的执行计划,因些我们应及时更新这些信息。
在Oracle8及以后的版本,Oracle列推荐用CBO的方式。
CBO的成本主要由物理I/O组成,计算公式为:
IO+CPU/1000+Net I/O*1.5
IO表示物理I/O请求,CPU表示逻辑I/O请求,Net I/O表示通过数据库链接访问远程数据库的逻辑I/O请求。
CBO会尝试计算所有可能执行的物理I/O,选择只需要最小物理I/O的计划。
ii.优化器的优化模式
优化模式包括Rule,Choose,First rows,All rows这四种方式。
1、Rule:基于规则的方式。
2、Choose:默认的情况下Oracle用的便是这种方式。
指的是当一个表或或索引有统计信息,则走CBO的方式,如果表或索引没有统计信息,表又不是特别的小,而且相应的列有索引时,那么就走索引,
走RBO的方式。
3、First Rows:它与Choose方式是类似的,所不同的是当一个表有统计信息时,它将以最快的方式返回查询的最先的几行,从总体上减少了响应时间。
4、All Rows:也就是我们所说的Cost的方式,当一个表有统计信息时,它将以最快的方式返回表的所有的行,从总体上提高查询的吞吐量。
没有统计信息则走基于规则的方式。
使用下列SQL语句可以修改优化器模式:
c)SQL优化过程
i.确定具有高影响力的SQL语句
在V$SQLAREA视图中的SQL语句将根据下列参数进行级别排序,这些参数是按照重要性由高到低进行排序的:
1、Executions(执行):经常执行的SQL语句就应当越早进行调整,因为它们会对总体性能产生巨大的影响。
2、Disk_reads(磁盘读取):高的磁盘读取量有可能表明查询导致了过多的输入输出量。
3、Rows_processed(记录处理):处理大量记录的查询会导致较高的输入输出量,同时在排序时有可能对TEMP表空间产生影响。
4、Buffer_gets(缓冲区读取):高的缓存读取量有可能表明了一个高资源使用量的查询。
5、Sorts(排序):排序会造成速度的明显降低,尤其是那些在磁盘TEMP表空间中进行的排序。
V$SQLAREA视图提供了一种识别有潜在问题或者需要优化的SQL语句的方法,可以使用下列SQL 语句找出执行开销高的语句。
ii.抽取和解释SQL语句
在指定SQL语句后,需要对它进行“解释”以丰富现存的执行计划,并且对它进行调整来确定这个执行计划是否可以改进。
在TOAD和PLSQL Developer中,可以使用Explain plan查看SQL语句的执行计划,在
SQL*Plus中可以使用Oracle AutoTrace查看SQL语句的执行计划,还可以使用Oracle提供的TKPROF工具、STATSPACK工具诊断和分析SQL语句可能存在的问题。
iii.调整SQL语句
我们将使用下列方法之一对拥有非优化执行计划的SQL语句进行调整:
d)SQL调整工具
i.Oracle AutoTrace
AUTOTRACE是一项SQL*Plus功能,自动跟踪为SQL语句生成一个执行计划并且提供与该语句的处理有关的统计。
1、在开始菜单->运行中,输入cmd,进入命令窗口,输入sqlplus命令,输入用户名:test,输入密
码:test,连接成功。
2、输入set autotrace on,表示启用autotrace查看sql执行计划。
输入SQL语句,在执行完成后,先显示SQL执行结果,然后显示SQL执行计划,最后显示SQL统计信息。
附:AUTOTRACE Statistics常用列解释
判断SQL 效率高低除了通过时间来衡量,还应该通过执行SQL 执行状态里面的逻辑读的数量来衡量:
逻辑读=(db block gets+ consistent gets )
ii. TKPROF 工具
TKPROF 是一个用于分析Oracle 跟踪文件并且产生一个更加清晰合理的输出结果的可执行工具。
如果一个系统的执行效率比较低,一个比较好的方法是跟踪用户的会话并使用TKPROF 工具的排序功能格式化输出,从而找出有问题的SQL 语句。
TKPROF 的使用遵循以下几个步骤:
在数据库级别上设置
TIMED_STATISTICS 为
true ,在SQL*Plus 中使用下列语句: TIMED_STATISTICS 为true 表示允许sql trace 和其他一些动态性能视图收集与时间有关的参数。
在session 级别设置trace ,在SQL*Plus 中使用下列语句: 3、找到生成的trace 文件,路径:Oracle 安装目录\admin\实例名\udump ,文件格式为:实例名_ora_编号.trc
4、对trace 文件使用TKPROF 工具进行分析
Tkprof tracefile outfile[explain=user/password][options …]
一般来说,使用TKPROF 得到的输出文件中包含3个部分:SQL 语句本身;相关的诊断信息,包括CPU 时间、总共消耗时间、读取磁盘数量、逻辑读数量、以及查询中返回的记录数目等。
例:在SQL*Plus 中输入下列语句:
Tkprof 输出文件中主要性能指标的说明:
i. STATSPACK 工具
Oracle Statspack 从Oracle8.1.6开始被引入Oracle,并马上成为DBA 和Oracle 专家用来诊断数据库性能的强有力的工具。
通过Statspack 我们可以很容易的确定Oracle 数据库的瓶颈所在,记录数据库性能状态,也可以使远程技术支持人员迅速了解你的数据库运行状况。
Statspack 的脚本位于$ORACLE_HOME\RDBMS\ADMIN\spcreate.sql
1. 安装STATSPACK
1、为了能够顺利安装和运行Statspack 你可能需要设置以下系统参数:
job_queue_processes
为了能够建立自动任务,执行数据收集,该参数需要大于0。
你可以在初试化参数文件中修改该参数(使该参数在重启后以然有效)。
该参数可以在系统级动态修改(重启后失效)。
在SQL*Plus 中输入下列语句:
timed_statistics
收集操作系统的计时信息,这些信息可被用来显示时间等统计信息、优化数据库和 SQL 语句。
要防止因从操作系统请求时间而引起的开销,请将该值设置为False。
使用statspack收集统计信息时建议将该值设置为 TRUE,否则收集的统计信息大约只能起到10%的作用,将timed_statistics设置为True所带来的性能影响与好处相比是微不足道的。
该参数使收集的时间信息存储在V$SESSTATS 和V$SYSSTATS等动态性能视图中。
Timed_statistics参数可以在实例级进行更改,在SQL*Plus中输入下列语句:
2
、创建Statspack需要使用的表空间和用户
3、安装Statspack
安装Statspack需要拥有SYSDBA(connect / as sysdba)权限的用户登陆。
在Oracle8.1.7以后版本中运行spcreate.sql。
首先登陆到数据库,最好转到$ORACLE_HOME/RDBMS/ADMIN目录,这样我们执行脚本就可以方便些。
执行完成,提示如下信息表示创建成功。
1. 生成分析报告
1、用statspack 用户帐号登录SQL*Plus
2、抓取快照,至少抓取2次以上,在SQL*Plus 中输入下列语句:
生成分析报告,,在SQL*Plus 中输入下列语句: 按照提示,依次输入begin_snap 、end_snap 和report_name 值。
生成的分析报告位于$ORACLE_HOME/RDBMS/ADMIN 目录下。
1. STATSPACK 收集选项
Statspack 有两种类型的收集选项: 级别(level ):控制收集数据的类型 门限(threshold ):设置收集的数据的阈值。
1、级别(level )
Statspack 共有三种快照级别,默认值是level 5
可以通过statspack 包修改缺省的级别设置
如果你只是想本次改变收集级别,可以忽略i_modify_parameter 参数。
2、快照门限
快照门限只应用于stats$sql_summary 表中获取的SQL 语句。
因为每一个快照都会收集很多数据,每一行都代表获取快照时数据库中的一个SQL 语句,所以stats$sql_summary 很快就会成为Statspack 中最大的表。
门限存储在stats$statspack_parameter 表中。
让我们了结一下各种门限:
任何一个门限值超过以上参数就会产生一条记录。
通过调用statspack.modify_statspack_parameter 函数我们可以改变门限的默认值。
例如:
2.STATSPACK分析报告详解
statspack 输出结果中必须查看的十项内容:
1、报表头信息
数据库实例相关信息,包括数据库名称、ID、版本号及主机等信息。
2、负载间档
该部分提供每秒和每个事物的统计信息,是监控系统吞吐量和负载变化的重要部分。
负载间档的统计指标的说明如下表:
3、实例命中率
该部分可以提前找出ORACLE潜在将要发生的性能问题,很重要。
实例命中率的统计指标的说明如下表:
Shared Pool相关统计数据
Shared Pool的统计指标的说明如下表:
5、首要等待事件
oracle等待事件是衡量oracle运行状况的重要依据及指示,主要有空闲等待事件和非空闲等待事件。
TIMED_STATISTICS:=TRUE,等待事件按等待的时间排序,= FALSE,等待事件按等待的数量排序。
运行statspack期间必须session上设置TIMED_STATISTICS = TRUE。
空闲等待事件是oracle 正等待某种工作,在诊断和优化数据库时候,不用过多注意这部分事件,非空闲等待事件专门针对oracle的活动,指数据库任务或应用程序运行过程中发生的等待,这些等待事件是我们在调整数据库应该关注的。
这里是比其他任何事件都能使速度减慢的事件。
比较影响性能的常见等待事件:
首要等待事件的统计指标的说明如下表:
数据库用户程序发生的所有等待事件
7、数据库后台进程发生的等待事件
8、TOP SQL
调整首要的25个缓冲区读操作和首要的25个磁盘读操作做的查询,将可对系统性能产生5%到5000%的增益。
在报表的这一部分,通过Buffer Gets对SQL语句进行排序,即通过它执行了多少个逻辑I/O来排序。
顶端的注释表明一个PL/SQL单元的缓存获得(Buffer Gets)包括被这个代码块执行的所有SQL 语句的Buffer Gets。
因此将经常在这个列表的顶端看到PL/SQL过程,因为存储过程执行的单独的语句的数目被总计出来。
这部分通过物理读对SQL语句进行排序。
这显示引起大部分对这个系统进行读取活动的SQL,即物理I/O。
这部分告诉我们在这段时间中执行最多的SQL语句。
为了隔离某些频繁执行的查询,以观察是否有某些更改逻辑的方法以避免必须如此频繁的执行这些查询,这可能是很有用的。
或许一个查询正在一个循环的内部执行,而且它可能在循环的外部执行一次,可以设计简单的算法更改以减少必须执行这个查询的次数。
即使它运行的飞快,任何被执行几百万次的操作都将开始耗尽大量的时间。
9、实例活动
10、I/O
下面两个报表是面向I/O的。
通常,在这里期望在各设备上的读取和写入操作是均匀分布的。
要找出什么文件可能非常“热”。
一旦DBA了解了如何读取和写入这些数据,他们也许能够通过磁盘间更均匀的分配I/O而得到某些性能提升。
11、缓冲池
如果我们使用多缓冲池的功能,上面的报表会告诉我们缓冲池引起的使用故障。
实际上这只是我们在报表的开头看到的信息的重复。
12、回滚段活动
一般期望活动在各回滚段间(除了SYSTEM回滚段外)均匀分布。
在检查报表的这一部分时,报表标题也具有需要记住的最有用信息。
尤其是,如果完全使用最佳设置时关于Optmal比Avg Active更大的建议。
因为这是与DBA最有关的活动(I/O和回滚段信息)。
a)Oracle SQL优化方法
i.选用适合的ORACLE优化器
ORACLE的优化器共有3种:RULE (基于规则)、COST (基于成本)、CHOOSE (选择性)。
设置缺省的优化器,可以通过对init.ora文件中OPTIMIZER_MODE参数的各种声明,如RULE, COST,CHOOSE,ALL_ROWS,FIRST_ROWS。
你当然也在SQL句级或是会话(session)级对其进行覆盖。
为了使用基于成本的优化器(CBO, Cost-Based Optimizer) , 你必须经常运行analyze 命令,以增加数据库中的对象统计信息(object statistics)的准确性。
如果数据库的优化器模式设置为选择性(CHOOSE),那么实际的优化器模式将和是否运行过analyze命令有关。
如果table已经被analyze过, 优化器模式将自动成为CBO , 反之,数据库将采用RULE形式的优化器。
在缺省情况下,ORACLE采用ALL_ROWS优化模式(使用CBO优化器), 为了避免那些不必要的全表扫描(full table scan) , 你必须尽量避免使用CHOOSE优化器,而直接采用基于规则或者基于成本的优化器。
ii.访问Table的方式
ORACLE 采用两种访问表中记录的方式:
1、全表扫描
全表扫描就是顺序地访问表中每条记录。
ORACLE采用一次读入多个数据块(database block)的方式优化全表扫描。
对于小表,使用全表扫描,速度最快。
2、通过ROWID访问表
你可以采用基于ROWID的访问方式情况,提高访问表的效率, ROWID包含了表中记录的物理位置信息。
ORACLE采用索引(INDEX)实现了数据和存放数据的物理位置(ROWID)之间的联系。
通常索引提供了快速访问ROWID的方法,因此那些基于索引列的查询就可以得到性能上的提高。
iii.共享SQL语句
为了不重复解析相同的SQL语句,在第一次解析之后, ORACLE将SQL语句存放在内存中。
这块位于系统全局区域SGA(system global area)的共享池(shared buffer pool)中的内存可以被所有的数据库用户共享。
因此,当你执行一个SQL语句(有时被称为一个游标)时,如果它和之前的执行过的语句完全相同, ORACLE就能很快获得已经被解析的语句以及最好的执行路径。
ORACLE的这个功能大大地提高了SQL的执行性能并节省了内存的使用。
可惜的是ORACLE只对简单的表提供高速缓冲(cache buffering) ,这个功能并不适用于多表连接查询。
数据库管理员必须在init.ora中为这个区域设置合适的参数,当这个内存区域越大,就可以保留更多的语句,当然被共享的可能性也就越大了。
当你向ORACLE 提交一个SQL语句,ORACLE会首先在这块内存中查找相同的语句。
这里需要注明的是,ORACLE对两者采取的是一种严格匹配,要达成共享,SQL语句必须完全相同(包括空格,换行等)。
共享的语句必须满足三个条件:
字符级的比较:当前被执行的语句和共享池中的语句必须完全相同。
例如:
2、两个语句所指的对象必须完全相同。
例如:
考虑一下下列SQL语句能否在这两个用户之间共享
3、两个SQL语句中必须使用相同的名字的绑定变量(bind variables)
例如:
第一组的两个SQL语句是相同的(可以共享),而第二组中的两个语句是不同的(即使在运行时,赋于不同的绑定变量相同的值)
i.选择最有效率的表名顺序
注意:只在基于规则的优化器中有效。
ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表 driving table)将被最先处理。
在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表。
当ORACLE处理多个表时, 会运用排序及合并的方式连接它们。
首先,扫描第一个表(FROM子句中最后的那个表)并对记录进行排序,然后扫描第二个表(FROM子句中最后第二个表),最后将所有从第二个表中检索出的记录与第一个表中记录进行合并。
如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表。
例如:
EMP表描述了LOCATION表和CATEGORY表的交集。
将比下列SQL更有效率
ii.WHERE子句中的连接顺序
ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE 条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾。
例如:
(低效)
(高效)
iii.SELECT子句中避免使用‘ * ‘
当你想在SELECT子句中列出所有的COLUMN时,使用动态SQL列引用‘*’是一个方便的方法.不幸的是,这是一个非常低效的方法。
实际上,ORACLE在解析的过程中, 会将’*’依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间。
iv.减少访问数据库的次数
当执行每条SQL语句时, ORACLE在内部执行了许多工作: 解析SQL语句, 估算索引的利用率, 绑定变量 , 读数据块等等。
由此可见, 减少访问数据库的次数 , 就能实际上减少ORACLE的工作量。
例如:以下有三种方法可以检索出雇员号等于342或291的职员。
方法1 (最低效)
方法2 (次低效)
方法3 (高效)
v.使用DECODE函数来减少处理时间
使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表。
例如:
你可以用DECODE函数高效地得到相同结果
类似的,DECODE函数也可以运用于GROUP BY 和ORDER BY子句中。
vi.删除重复记录
最高效的删除重复记录方法 ( 因为使用了ROWID)
vii.用TRUNCATE替代DELETE
当删除表中的记录时,在通常情况下, 回滚段(rollback segments ) 用来存放可以被恢复的信息. 如果你没有COMMIT事务,ORACLE会将数据恢复到删除之前的状态(准确地说是恢复到执行删除命令之
前的状况)。
而当运用TRUNCATE时, 回滚段不再存放任何可被恢复的信息。
当命令运行后,数据不能
被恢复。
因此很少的资源被调用,执行时间也会很短。
(TRUNCATE只在删除全表适用,TRUNCATE是DDL
不是DML)。
viii.HWM对数据库性能的影响
1、什么是HWM?
所有的oracle段(segments,在此,为了理解方便,建议把segment作为表的一个同义词) 都有一个在段内容纳数据的上限,我们把这个上限称为"high water mark"或HWM,即高水位线。
这个HWM 是一个标记,用来说明已经有多少没有使用的数据块分配给这个segment。
HWM通常增长的幅度为一
次5个数据块,原则上HWM只会增大,不会缩小,即使将表中的数据全部删除,HWM还是为原值,由
于这个特点,使HWM很象一个水库的历史最高水位,这也就是HWM的原始含义,当然不能说一个水库没水了,就说该水库的历史最高水位为0。
但是如果我们在表上使用了truncate命令,则该表的HWM 会被重新置为0。
2、HWM数据库的操作有如下影响:
15、全表扫描通常要读出直到HWM标记的所有的属于该表数据库块,即使该表中没有任何
数据。
16、即使HWM以下有空闲的数据库块,如果在插入时使用HWM以上的数据块,此时HWM会
自动增大
3、如何知道一个表的HWM?
17、首先对表进行分析:
18、查询user_tables表
HWM=BLOCKS-EMPTY_BLOCKS-1。
其中BLOCKS 列代表该表中曾经使用过的块的数目。
EMPTY_BLOCKS 代表分配给该表,但是在水位线以上的数据库块,即从来没有使用的数据块。
1表示
每一个segment都有一个固定块用于保存segment header信息。
4、降低ORACLE表的高水位线
在ORACLE中,执行对表的删除操作不会降低该表的高水位线。
而全表扫描将始终读取一个段(extent)中所有低于高水位线标记的块。
如果在执行删除操作后不降低高水位线标记,则将导致查询语句的性能低下。
下面的方法都可以降低高水位线标记:
i.尽量多使用COMMIT
只要有可能,在程序中尽量多使用COMMIT, 这样程序的性能得到提高,需求也会因为COMMIT所释放的资源而减少,COMMIT所释放的资源:
1、回滚段上用于恢复数据的信息。
2、程序语句获得的锁。
3、redo log buffer 中的空间。
4、ORACLE为管理上述3种资源中的内部花费
(注: 在使用COMMIT时必须要考虑事务的完整性,现实中效率和事务完整性往往是鱼和熊掌不可得兼)
ii.用Where子句替换HAVING子句
避免使用HAVING子句, HAVING 只会在检索出所有记录之后才对结果集进行过滤,这个处理需要排序,总计等操作。
如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销。
例如:
(低效)
(高效)。