Oracle 学习总结 - 表和索引的性能优化

表的性能

表的性能取决于创建表之前所应用的数据库特性,数据库->表空间->表,创建数据库时确保为每个用户创建一个默认的永久表空间和临时表空间并使用本地管理,创建表空间设为本地管理并且自动段空间管理

本地管理表空间在每个数据文件中使用一个位图来管理对象扩展和空闲空间

查看数据库相关配置

 SELECT * FROM DATABASE_PROPERTIES
SELECT * FROM V$PARAMETER

查看表空间相关配置

select* from DBA_TABLESPACES
主要表类型 描述及用法
堆组织表 一般默认类型
临时表 基于会话或事物期间的临时表,结束后销毁
索引组织表 按照主键排序的B+树索引结构中,提供快速读取
分区表 由多个相互分隔开的物理段组成的逻辑表
物化视图 包含sql查询结果的表,聚集数据以快速提供报表或复制数据
聚簇 共享相同存储的一组表,减少io

提升表性能的建议,使用正确的数据类型,是数字就用数据,精度可以确定就指定精度,是日期就是使用日期类型,变长使用varchar2,当需要从Null更新到大值时适当调大pctfree防止过多的行链接影响数据块读取性能,主键索引等的合理设计,尽量减少lob的使用,如果都非空就设置not null

oracle 11gr2之后,将表及索引的物理空间分配延迟到第一条记录插入到表时,通过查询'user_segments'和'user_extents'验证

如果需要将大量数据加载到表中,如果数据非关键可轻易重建或者导入后立马备份,可以设置nologging使直接路径操作产生的重做日志最小化并使用直接路径加载

alter table *** nologging;
insert /*+append*/ into *** select * from xxx;

高效移除表中数据,truncate会将高水位线归零(全表扫描仅搜索高水位线之下的存储块中的数据行),释放空间(reuse storage),受外键约束/delete产生大量的撤销和重做日志,可回退,如果用drop重建,必须同时重建所有索引约束授权触发器等,并且在重建完成之前不可用

通过v$transaction查询事物细节

查看顾问运行的时间

select * from dba_auto_segadv_summary

生成的相关结果表

dba_advisor_findings
dba_advisor_objects
dba_advisor_executions

查看顾问段的建议的工具,是否有建议需要收缩,移动或压缩的表

select * from table(dbms_space.asa_recommendations('false','false','false'))

更新一行数据,当空余空间无法容纳数据,则当前数据块中存储指针,指向新的数据块,成为行链接,查询时需要访问多个数据块影响性能,需要Move,移动过程中会上锁。移动完后数据行会被分配新的rowid,所以需要重建索引等

alter table tt move /* pctfree 40 */;
alter index itt rebuild;

通过dba_indexs和user_tables等表可以验证

ROWID唯一标识一个数据行,但不同表中的数据行存储在同一个聚簇中可能会有相同的值

如果表太闲,闲置空间太多,需要收缩并调整高水位线,用占用最小存储空间的方式重新组织数据块并重新调整表的高水位线

alter table tt entable row movement;
alter table tt shrink space /*compact 不重新调整水位线*/ ;

数据表压缩,将数据表数据压缩在较少的数据块中,从而在接下来的过程中使用较少的io,还有很多付费的高级压缩方式

alter table tt compress;
//已存数据也
alter table tt move compress;

索引及性能优化

需要考虑什么:

正确添加索引,能提高查询速度,减少查询io,但会增加索引的存储空间,并且当数据修改时要对应修改索引,增加消耗。

索引的类型 用法
B树索引 高基数列使用,创建rowid和列值组成的条目,每个条目中rowid指向
B树聚簇索引  键物理排序放在一起
散列聚簇索引  
基于函数的索引  某个函数常常出现在where语句中,加这个
虚拟列索引  
反转键索引  按照序列插入某值,会导致某个索引块过热争用频繁,所以定义反转索引减少争用,但缺点是不支持范围搜索
键值压缩索引  某个索引前导列有大量重复值,定义压缩减少访问io
位图索引  低基数列创建,适合基本不更新的,因为大面积锁表
位图连接索引  索引中包含where子句,将连接结果存储在索引中
全局分区索引  分区表各个分区一个全局索引
本地分区索引  分区表每个分区一个索引

为优化器提供最新的信息

exec dbms_stats.gather_table_stats(ownname=>'SYSTEM', tabname=>'TT',cascade=>true);

b树索引查询的集中情况:

create index itt on tt(id)

1. 查询所需要的所有表数据都包含在索引结构中

索引范围扫描:select id from tt where id=1;     INDEX RANGE SCAN, consistent gets 只访问索引块即可获得数据

索引快速全扫描:select count(id) from tt where id=2;  INDEX FAST FULL SCAN, consistent gets 仅全部访问索引即可得到结果

2. 查询需要的信息并非都包含在索引数据块中,因此查询需要访问索引和表,即需要回表

select id,name from tt where id=1;  TABLE ACCESS BY INDEX ROWID/INDEX RANGE SCAN,consistent gets先访问索引找到对应的数据块,再通过rowid找到对应数据块读

3. 不访问索引,全表扫描

select * from tt;  TABLE ACCESS FULL, consistent gets 都为数据块访问

需要建立索引的情况:

为每张表创建主键约束,自动为主键列创建索引,在需要保持唯一的非空列上创建唯一索引,将会在唯一键约束所声明的列上自动创建一个索引,在外键列上创建索引,where后出现频率高的

创建没有数据段的索引,永远不会使用并且永远不会为其分配盘区的索引,可以预先测试确定优化器是否会使用到它

alter session set "_use_nosegment_indexes"=true;
set autotrace trace explain;
/*查询看是否使用到索引*/

创建主键索引

alter table tt add constraint itt primary key (id)

查看当前某张表上的所有约束和索引

select * from user_constraints where table_name ='TT';
select * from user_indexes where table_name ='TT';

创建唯一索引

alter table tt add constraint utt unique (name)

创建外键索引

alter table tt1 add constraint agepk foreign key (id1) references tt(id)

组合索引在非前导情况,优化器选择INDEX SKIP SCAN也会用到索引

通过压缩处理在一个索引列中,某行具有大量重复值的情况,节省存储空间,在叶子数据块中存储更多的值,减少io的访问

create index ttt on tt1(age) compress 1 /* nocompress */

基于函数的索引

create index funt on tt(upper(name))

索引虚拟列

反转索引,使用序列来填充主键列,会导致索引资源争夺,因为值近似,导致对同一个数据块的多次插入,引起争夺。缺点是不支持范围扫描

create index rtt on tt(address) reverse

还可以新增一个不影响已有应用,优化器不可见 invisible,第三方应用不可见并且在删除之前设为不可见,确定不能删除再删除

对于星型架构的数据仓库,一张很大的事实表和一系列维度表组成,存储数据行的rowid和位图,适合低基数列,基本不会更新,因为会大面积锁表

位图连接索引将两张表的连接结果保存在索引中,避免了表连接,这种索引可以包含where 子句,适用于数据仓库,表加载后不会进行更新

索引组织表,将表中数据行的所有内容存储在一个B树索引中

上一篇:Oracle的表连接方式


下一篇:2015年我国IT行业发展趋势分析(转)