经过长时间学习Oracle primary索引,于是和大家分享一下,看完本文你肯定有不少收获,希望本文能教会你更多东西。有经验的Oracle DBA都知道I/O是响应时间的***组成部分。其中磁盘I/O特别厉害,因为当Oracle由磁盘上的一个数据文件得到一个数据块时,读的进程就必须等待物理I/O操作完成。磁盘操作要比数据缓冲慢10,000倍。因此,如果可以令I/O最小化,或者减少由于磁盘上的文件竞争而带来的瓶颈,就可以大大地改善Oracle数据库的性能。
如果系统响应很慢,通过减少磁盘I/O就可以有一个很快的改善。如果在一个事务中通过按一定的范围搜索Oracle primary索引来访问表,那么重新以CTAS的方法组织表将是你减少I/O的首要策略。通过在物理上将行排序为和Oracle primary索引一样的顺序,就可以加快获得数据的速度。
就象磁盘的负载平衡一样,行的重新排序也是很简单的,而且也很快。通过与其它的DBA管理技巧一起使用,就可以在高I/O的系统中大大地减少响应的时间。
在高容量的在线事务处理环境中(online transaction processing,OLTP),数据是由一个Oracle primary索引得到的,重新排序表格的行就可以令连续块的顺序和它们的Oracle primary索引一样,这样就可以在索引驱动的表格查询中,减少物理I/O并且改善响应时间。这个技巧仅在应用选择多行的时候有用,或者在使用索引范围搜索和应用发出多个查询来得到连续的Key时有效。对于随机的唯一primary-key(主键)的访问将不会由行重新排序中得到好处。
让我们看一下它是如何工作的。考虑以下的一个SQL的查询,它使用一个索引来得到100行:
这个查询将会使用last_name_index,搜索其中的每一行来得到目标行。这个查询将会至少使用100次物理磁盘的读取,因为employee的行存放在不同的数据块中。
不过,如果表中的行已经重新排序为和last_name_index的一样,同样的查询又会怎样处理呢?我们可以看到这个查询只需要三次的磁盘I/O就读完全部100个员工的资料(一次用作索引的读取,两次用作数据块的读取),减少了97次的块读取。

重新排序带来的性能改善的程度在于在你开始的时候行的乱序性如何,以及你需要由序列中访问多少行。至于一个表中的行与索引的排序键的匹配程度,可以查看数据字典中的dba_indexes和dba_tables视图得到。
在dba_indexes的视图中,查看clustering_factor列。如果clustering_factor的值和表中的块数目大致一样,那么你的表和索引的顺序是一样的。不过,如果clustering_factor的值接近表中的行数目,那就表明表格中的行和索引的顺序是不一样的。
行重新排序的作用是不可以小看的。在需要进行大范围的索引搜索的大表中,行重新排序可以令查询的性能提高三倍。
一旦你已经决定重新排序表中的行,你可以使用以下的工具之一来重新组织表格。◆使用Oracle的Create Table As Select (CTAS)语法来拷贝表格◆Oracle9i自带的表格重新组织工具
【编辑推荐】
oracle 什么时候 使用分区表
1、表的大小超过2GB。 2、表中包含历史数据,新的数据被增加到新的分区中。 (3).表分区的优缺点表分区有以下优点: 1、改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索速度。 2、增强可用性:如果表的某个分区出现故障,表在其他分区的数据仍然可用;3、维护方便:如果表的某个分区出现故障,需要修复数据,只修复该分区即可;4、均衡I/O:可以把不同的分区映射到不同磁盘以平衡I/O,改善整个系统性能。 缺点: 分区表相关:已经存在的表没有方法可以直接转化为分区表。 不过 Oracle 提供了在线重定义表的功能。
SQL server中 表中如何创建索引?
if exists(select *From where naem = newindex) drop index newindex create index --=================================== 竟然没有悬赏...唉... 那算了吧 我还是都告诉你吧.. 看个示例 自己琢磨去: --============================================== use master go if db_id(Nzhangxu)is not null drop database zhangxu go create database zhangxu sp_helpdb zhangxu use zhangxu go IF EXISTS (SELECT *FROM WHERE NAME = NWORKER) DROP TABLE WORKER GO create table worker (w_id int identity (1000,1) not null,w_name Nvarchar(10) unique,w_age SMALLINT CONSTRAINT CK_W_AGE CHECK(w_age>20 and w_age<150),w_pay money DEFAULT 0,CONSTRAINT PK_W_ID PRIMARY KEY(W_ID) ) SELECT *FROM WORKER--用查询技术查看表信息 sp_help worker--利用存储过程查看表信息 /* 创建简单的非聚集索引 */ USE ZHANGXU GO if exists(select name from where name = NIX_ID_NAME) DROP INDEX IX_ID_NAME on worker go--检查是否存在索引,有则删除索引 create index IX_ID_NAME--创建索引 on worker(w_id,w_name)--在ID NAME 两个字段上创建非聚集索引 drop index _ID_NAME--删除索引 select *from where name = IX_ID_NAME--查看索引 /* 创建唯一非聚集索引 */ USE ZHANGXU GO IF EXISTS(SELECT NAME FROM WHERE NAME = NIX_W_NAME) DROP INDEX IX_W_NAME ON WORKER GO CREATE UNIQUE INDEX IX_W_NAME--唯一非聚集索引 ON WORKER(W_NAME) /* 查看索引T-SQL脚本 */ --IX_W_NAME 唯一 非聚集索引 USE [zhangxu] GO /****** 对象: Index [IX_W_NAME] 脚本日期: 07/29/2007 16:54:53 ******/ CREATE UNIQUE NONCLUSTERED INDEX [IX_W_NAME] ON [dbo].[worker] ([w_name] ASC ) WITH ( SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF ) ON [PRIMARY] --PK_W_ID聚集索引 USE [zhangxu] GO /****** 对象: Index [PK_W_ID] 脚本日期: 07/29/2007 16:56:45 ******/ ALTER TABLE [dbo].[worker] ADD CONSTRAINT [PK_W_ID] PRIMARY KEY CLUSTERED ([w_id] ASC ) WITH ( SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF ) ON [PRIMARY] --UQ_WORKER 唯一,非聚集索引 USE [zhangxu] GO /****** 对象: Index [UQ__worker__F21] 脚本日期: 07/29/2007 16:58:38 ******/ ALTER TABLE [dbo].[worker] ADD UNIQUE NONCLUSTERED ([w_name] ASC ) WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF ) ON [PRIMARY] select *from worker insert into worker(w_name,w_age,w_pay) values(王国龙,25,4500)
sql语句中raiserror和return的区别
RAISERROR 返回用户定义的错误信息并设系统标志,记录发生错误。 通过使用 RAISERROR 语句,客户端可以从 sysmessages 表中检索条目,或者使用用户指定的严重度和状态信息动态地生成一条消息。 return从查询或过程中无条件退出,不执行位于return之后的语句。
发表评论